如何有效地转换List ?
我有一个
List
但我需要一个
List
有没有办法在c#中强制转换? 或者使用Linq获得相同的结果?
我有两个实现相同接口的类:
interface IDataField { } class InputField : IDataField { } class PurchaseField : IDataField { }
此列表来自Linq-to-Sql查询:
List list = (from i .... select i).ToList();
.OfType
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?