如何有效地转换List <t>?</t>

时间:2009-02-02 20:24:03

标签: c# linq-to-sql

我有一个

List<InputField> 

但我需要一个

List<IDataField>  

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

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

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

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

List<InputField> list = (from i .... select i).ToList();

8 个答案:

答案 0 :(得分:39)

两者.OfType&lt; T&gt;和.Cast&lt; T&gt;将返回T的列表,但这两种方法的含义是不同的。

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

list.Cast 强制转换原始列表中的所有项目都输入T,并为无法转换为该类型的项目抛出异常。

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

List<InputField> list = (from i .... select i).Cast<IDataField>.ToList();

答案 1 :(得分:11)

List<InputField> raw = (from i .... select i).ToList();
List<IDataField> result = raw.OfType<IDataField>().ToList();

答案 2 :(得分:7)

您也可以使用 List.ConvertAll

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

示例:

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

答案 3 :(得分:5)

由于列表来自

List<InputField> list = (from i .... select i).ToList();

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

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

如果这不起作用,IEnumerable的“Cast”扩展可能会起作用:

List<DataField> list2 = list.Cast<IDataField>();

答案 4 :(得分:3)

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

原因是您可以对此List<Bangle>进行两次引用。如果第二个引用强制转换然后将其引用为List<Akthud>,则允许向其添加Akthud - 但现在第一个引用具有List<Bangle>,其成员不是全部Bangle秒。违反!

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

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

答案 5 :(得分:1)

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

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

答案 6 :(得分:1)

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

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

List<IDataField> ls = (List<IDataField>)List<InputField>

从我的搜索到目前为止,我的结论是.Net从3.5开始不支持此功能。因此,我们最终必须采用变通方法。

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

答案 7 :(得分:0)

我有以下字符串

 var str = "2 4 7 8 10";

当我按如下方式投射时

var numbersInt2 = numbers.Split(' ')
                .ToList().Cast<int>().ToList();

它返回一个异常,但是

  

System.InvalidCastException:'指定的转换无效。

(如果使用以下

var numbersInt = numbers.Split(' ')
                .ToList().ConvertAll(int.Parse);

有效。