如何将List <object>转换为List <SomethingElse>

Ian*_*oyd 50 c# generics

我怎样才能施放List<object>List<SomethingElse>

(已知来自哪里SomethingElseobject)


奖金Chatter

铸造清单:

List<Object> first = ...;

List<SomethingElse> second = (List<SomethingElse>)first;
Run Code Online (Sandbox Code Playgroud)

不起作用:

无法将类型'System.Collections.Generic.List'转换为'System.Collections.Generic.List'

铸造清单:

List<SomethingElse> second = first.Cast<SomethingElse>();
Run Code Online (Sandbox Code Playgroud)

不起作用:

不能将类型'System.Collections.Generic.List'隐式转换为'System.Collections.Generic.List'

我实际上并不需要完整的List<T>对象,只是一个ICollection<T>意志:

ICollection<SomethingElse> second = first;
ICollection<SomethingElse> second = (ICollection<SomethingElse>)first;
ICollection<SomethingElse> second = first.Cast<SomethingElse>();
Run Code Online (Sandbox Code Playgroud)

不工作.

Dou*_*las 37

LINQ,通过类中的扩展方法实现Enumerable,依赖于延迟执行:

返回值序列的查询中使用的方法在枚举查询对象之前不会使用目标数据.这称为延迟执行.

Cast<T>不会立即创建新列表,而是存储执行操作所需的所有信息.该列表仅在需要时才会被枚举(例如,通过foreach语句).

在你的情况下,如果你只是想重复序列,你应该考虑坚持IEnumerable<T>接口,这是声明的返回类型Cast<T>:

IEnumerable<SomethingElse> second = first.Cast<SomethingElse>();
foreach (SomethingElse se in second)
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为它只在每个项目被迭代时执行强制转换.

如果您确信要立即创建新列表,请使用ToList:

List<SomethingElse> second = first.Cast<SomethingElse>().ToList();
Run Code Online (Sandbox Code Playgroud)

编辑:回复评论中发布的点:

这取决于你所说的"可以修改的列表".有几个LINQ查询运算符允许您进一步更改查询的定义.例如,如果要删除SomethingElseIsDeleted属性所属的所有元素true,可以使用Where运算符:

IEnumerable<SomethingElse> second = first.Cast<SomethingElse>();
second = second.Where(element => !element.IsDeleted);
Run Code Online (Sandbox Code Playgroud)

如果要添加一系列新元素,可以使用Concat运算符:

second = second.Concat(anotherCollectionOfSomethingElse);
Run Code Online (Sandbox Code Playgroud)

如果要按升序对序列进行排序ID,请使用OrderBy运算符:

second = second.OrderBy(element => element.ID);
Run Code Online (Sandbox Code Playgroud)

每次,我们都在查询的前一个定义上应用查询运算符,并将新的(复合)查询分配给我们的second变量.LINQ会将所有运算符存储在查询定义中.然后,当实际枚举序列时(例如,通过a foreachToList),它将为您提供序列的复合结果,并按顺序应用所有查询运算符.

与延迟执行/延迟评估的所有情况一样,请注意不要过度使用此功能.例如,如果你要应用一个Where会大大减小序列大小的运算符,那么急切地执行查询并存储枚举列表可能是有意义的.


Mat*_*ard 18

我觉得你接近这个Cast<T>表达方式.区别在于Cast<T>返回a IEnumerable<T>而不是a List<T>.

试试这个:

IEnumerable<SomethingElse> second = first.Cast<SomethingElse>();
Run Code Online (Sandbox Code Playgroud)

您可以通过执行类似操作来获取列表:

List<SomethingElse> second = first.Cast<SomethingElse>().ToList();
Run Code Online (Sandbox Code Playgroud)


Cha*_*ert 16

您可以选择使用CastOfType.Cast如果你不能转换为指定的类型,将抛出异常.OfType另一方面,只返回列表中可以转换为指定类型的项目.我建议OfType在你的情况下使用.

List<Foo> fooList = myList.OfType<Foo>().ToList();
Run Code Online (Sandbox Code Playgroud)