如何在C#中将IEnumerable<T>转换为List<T>?

17

我正在使用LINQ查询一个通用字典,并将结果作为我的ListView(WebForms)的数据源。

简化后的代码:

Dictionary<Guid, Record> dict = GetAllRecords();
myListView.DataSource = dict.Values.Where(rec => rec.Name == "foo");
myListView.DataBind();

我原本以为这样可以工作,但实际上它会抛出一个System.InvalidOperationException异常:

id为'myListView'的ListView必须具有一个实现ICollection或可以执行数据源分页(如果AllowPaging为true)的数据源。

为了使它能够正常工作,我不得不采用以下方式:

Dictionary<Guid, Record> dict = GetAllRecords();
List<Record> searchResults = new List<Record>();

var matches = dict.Values.Where(rec => rec.Name == "foo");
foreach (Record rec in matches)
    searchResults.Add(rec);

myListView.DataSource = searchResults;
myListView.DataBind();

第一个示例中是否存在小问题需要解决才能使其正常工作?

(对于这个问题的标题我不确定该使用什么,可以自由编辑为更合适的内容)


这是 https://dev59.com/sXRB5IYBdhLWcg3w6LR2 的相反操作。 - John
5个回答

29

尝试这个:

var matches = dict.Values.Where(rec => rec.Name == "foo").ToList();

请注意,这实际上将从原始“Values”集合创建一个新列表,因此对字典的任何更改都不会自动反映在绑定控件中。


9

我倾向于使用新的Linq语法:

myListView.DataSource = (
    from rec in GetAllRecords().Values
    where rec.Name == "foo"
    select rec ).ToList();
myListView.DataBind();

当你不使用钥匙时,为什么要获取字典?这会增加额外的负担。


@Keith:我在代码的其他地方使用了字典中的Guid键,因此可以通过记录ID获取记录。关于语法,我们可以同意不同意 ;) - Christian Hagelid

3
你可以尝试以下方法:
var matches = new List<Record>(dict.Values.Where(rec => rec.Name == "foo"));

基本上,通用集合非常难以直接转换,因此您真的只能创建一个新对象。

1
myListView.DataSource = (List<Record>) dict.Values.Where(rec => rec.Name == "foo");

@lomaxx:你的第一个解决方案不起作用。我似乎无法将 where 子句的结果强制转换为 List<Record>。它会导致以下运行时异常:无法将类型为 '<WhereIterator>d__01[Record]' 的对象强制转换为类型 'System.Collections.Generic.List1[Record]'。 你的第二个解决方案和Matt Hamiltons的都很好用。我已经接受了[Matt Hamiltons](http://stackoverflow.co - Christian Hagelid

0

仅仅是增加知识,下一句话不会从数据库中恢复任何数据。它只创建查询(因此它是可查询类型)。要启动此查询,您必须在末尾添加 .ToList() 或 .First()。

dict.Values.Where(rec => rec.Name == "foo")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接