我如何转换 List<object>
至 List<SomethingElse>
?
(已知 SomethingElse
源自 object
)
奖金聊天
列出名单:
List<Object> first = ...;
List<SomethingElse> second = (List<SomethingElse>)first;
不起作用:
Cannot convert type 'System.Collections.Generic.List' to 'System.Collections.Generic.List'
列出名单:
List<SomethingElse> second = first.Cast<SomethingElse>();
不起作用:
Cannot implicitely convert type 'System.Collections.Generic.List' to 'System.Collections.Generic.List'
我实际上并不需要完整的 List<T>
对象,只是一个 ICollection<T>
会做:
ICollection<SomethingElse> second = first;
ICollection<SomethingElse> second = (ICollection<SomethingElse>)first;
ICollection<SomethingElse> second = first.Cast<SomethingElse>();
不工作。
最佳答案
LINQ,通过 Enumerable
中的扩展方法实现类,依赖于延迟执行:
Methods that are used in a query that returns a sequence of values do not consume the target data until the query object is enumerated. This is known as deferred execution.
Cast<T>
不会立即创建新列表,而是存储执行操作所需的所有信息。该列表只会在需要时被枚举(例如,通过 foreach
语句)。
在您的情况下,如果您只是打算遍历序列,则应考虑坚持使用 IEnumerable<T>
接口(interface),它是 Cast<T>
的声明返回类型:
IEnumerable<SomethingElse> second = first.Cast<SomethingElse>();
foreach (SomethingElse se in second)
{
// ...
}
这是高效的,因为它只在迭代每个项目时执行转换。
如果您确信要立即创建一个新列表,请使用 ToList
:
List<SomethingElse> second = first.Cast<SomethingElse>().ToList();
编辑:回复评论中的观点:
这取决于你所说的“可以修改的列表”是什么意思。有几个 LINQ 查询运算符允许您进一步更改查询的定义。例如,如果要删除所有 SomethingElse
IsDeleted
的元素属性是 true
, 您可以使用 Where
运算符(operator):
IEnumerable<SomethingElse> second = first.Cast<SomethingElse>();
second = second.Where(element => !element.IsDeleted);
如果你想添加一系列新元素,你可以使用Concat
运算符(operator):
second = second.Concat(anotherCollectionOfSomethingElse);
如果您想按 ID
的升序对序列进行排序, 使用 OrderBy
运算符(operator):
second = second.OrderBy(element => element.ID);
每次,我们都在查询的先前定义上应用查询运算符,并将新的(复合)查询分配给我们的 second
多变的。 LINQ 会将所有运算符存储在查询定义中。然后,当实际枚举序列时(例如,通过 foreach
或 ToList
),它将为您提供序列的复合结果,并按顺序应用所有查询运算符。
对于所有延迟执行/懒惰评估的情况,请注意不要过度使用它。例如,如果您要申请 Where
运算符会大大减少序列的大小,因此急切地执行查询并存储枚举列表可能是有意义的。
关于c# - 如何将 List<object> 转换为 List<Something Else>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8933434/