2010-01-04 57 views
11

如果我有对象A实现ISomeInterface转换清单列表的接口

我为什么不能做到这一点:

List<objectA> list = (some list of objectAs . . .) 

List<ISomeInterface> interfaceList = new List<ISomeInterface>(list); 

为什么我不能粘在列表进入interfaceList构造?有什么解决方法吗?

回答

23

在C#3.0 + 3.5的.Net和高达你可以这样做解决这个问题下面

List<ISomeInterface> interfaceList = new List<ISomeInterface>(list.Cast<ISomeInterface>()); 

之所以这样不起作用的是,在这种情况下,构造函数List<ISomeInterface>需要一个IEnumerable<ISomeInterface>。列表变量的类型虽然只能转换为IEnumerable<objectA>。尽管objectA可转换为ISomeInterface,但IEnumerable<objectA>型不可转换为IEnumerable<ISomeInterface>

虽然在C#4.0中进行了修改,但它为语言添加了Co和Contravariance支持并允许进行此类转换。

+1

@itowlson,这是用户在样本中做的事情。他们没有指定添加行为是所需解决方案的一部分。 – JaredPar 2010-01-04 05:52:33

+1

你的意思是.NET 3.5,而不是C#3.5。 – 2010-01-04 06:26:26

1

这是在C#4.0中处理的,你不能在C#3.5中直接执行此操作。然而,你可以从这个列表中创建一个新列表,并使用一个扩展操作符或foreach来干净地完成它,尽管它比C#4中的 协变性 协变性提供的类型要慢(尽管得到这些错误)。

+1

见我来贾里德评论 - 没有C#3.5这样的东西。 – 2010-01-04 06:27:41

+0

Arg,让我想起Futurama中的美男。尽管说Linq WAS是一种语言变化,并且直到C#3.5才被引入,所以C#是2.0,直到它被赋予了linq扩展,WCF只是3.0中的一个框架升级。 – Spence 2010-01-04 20:37:38

3

最简单的&短的方法是:

var interfaceList = list.Cast<ISomeInterface>().ToList() 

OR

List<ISomeInterface> interfaceList = list.Cast<ISomeInterface>().ToList() 

上述两个示例代码都是平等的,你可以用你想每一个...

+0

使用ToList()的右侧是个好主意! 但请注意,使用var你隐藏变量的实际类型,这是不好的做法。 List interfaceList = list.Cast ()。ToList(); 所以我去使用这种形式作为最清晰,最短的版本 – 2015-12-26 12:41:58

+0

@KovácsEde,根据你提到的点,我添加了第二种方式来回答这个问题,但他们都是平等的。当我们使用'var'时,实际上我们正在以更短的格式编写我们的代码,并且总是可以通过查看'='的右侧来识别变量的类型。另一方面,即使我们使用'var',C#编译器也足以识别变量的实际类型。所以如果你想要更短的语法,使用'var'并且从'='右边的代码中识别变量类型,否则你可以使用第二种格式。 – RAM 2015-12-29 14:31:27