如何有效地转换List ?

我有一个

List 

但我需要一个

 List 

有没有办法在c#中强制转换? 或者使用Linq获得相同的结果?

我有两个实现相同接口的类:

 interface IDataField { } class InputField : IDataField { } class PurchaseField : IDataField { } 

此列表来自Linq-to-Sql查询:

 List list = (from i .... select i).ToList(); 

.OfType 和.Cast 都将返回T列表,但两种方法的含义不同。

list.OfType 过滤原始列表并返回T类型的所有项目,并跳过那些不属于该类型的项目。

list.Cast 原始列表中的所有项目转换为类型T,并为无法转换为该类型的项目抛出exception。

在你的情况下,两者都会给出相同的结果,但使用.Cast可以更清楚地传达你的意图,所以我建议使用它。

 List list = (from i .... select i).Cast.ToList(); 
 List raw = (from i .... select i).ToList(); List result = raw.OfType().ToList(); 

您也可以使用List.ConvertAll

文档: http : //msdn.microsoft.com/en-us/library/73fe8cwf.aspx

例:

 List newList = oldList.ConvertAll(i => i as IDataField); 

由于列表来自

 List list = (from i .... select i).ToList(); 

难道你不能只修复“选择我”部分而不是返回IDataField吗? 像这样的东西:

 List list = (from i .... select (IDataField)i).ToList(); 

如果这不起作用,也许IEnumerable的“Cast”扩展可以工作:

 List list2 = list.Cast(); 

以防万一:我的C#体验很少,但如果这种通用结构与Java相同,那么你必须创建一个由超类型参数化的全新List。 换句话说,如果Bangle每个实例也是Akthud的实例,那么并不是每个List也是List

这样做的原因是你可以对这个List有两个引用。 如果第二个引用转换然后将其作为List ,则允许向其添加Akthud – 但现在第一个引用具有List其成员不是所有Bangle s。 违反!

话虽这么说,大卫B的答案确实应该做到你想要的,正确的,AFAICT。 (看起来像是一个复制操作。)

[如果我误解了C#generics的语义,我希望有人在评论中纠正我!]

我不知道直接演员会产生预期效果。 我做过这种情况很少见,通常是这样的:

 List list = ..... List list2 = new (List((IDataField[])list.ToArray())); 

ConvertAll似乎是一个更好的解决方案,因为它不依赖于Linq库,而且更短更直观。

但是它们都是解决方案而不是解决方案。 它们都创建了具有相同数据的新集合。 应该支持.net中的通用协方差,即通用集合中的向上转换,这将允许您自然地这样做。 例如:

 List ls = (List)List 

从我的搜索到目前为止,我的结论是.Net从3.5开始不支持此function。 因此,我们必须以变通方法结束。

以下是关于该主题的讨论:

  • C#generics协方差
  • 协变通用列表
  • Generics Covariant,Contra-Variant还是Invariant?