将<int>列入IEnumerable <icomparable> </icomparable> </int>

时间:2013-02-22 16:51:23

标签: c# list ienumerable icomparable

我可以隐式地将一个int转换为IComparable。我也可以将一个List或一个数组转换为IEnumerable。

但为什么我不能隐式地将List强制转换为IEnumerable?

我使用.net framework 4.5和Visual Studio 2012 Ultimate测试了这个。

要测试的代码:

IComparable test1;
int t1 = 5;
test1 = t1; //OK

IEnumerable<int> test2;
List<int> t2 = new List<int>();
int[] t3 = new int[] { 5, 6 };
test2 = t2; //OK
test2 = t3; //OK

TabAlignment[] test;

IEnumerable<IComparable> test3;
test3 = t2; //error Cannot implicitly convert type 'System.Collections.Generic.List<int>' to 'System.Collections.Generic.IEnumerable<System.IComparable>'. An explicit conversion exists (are you missing a cast?)

2 个答案:

答案 0 :(得分:13)

基本上,通用方差不适用于值类型。所以当你可以

您需要打包每个值:

IEnumerable<IComparable> test3 = t2.Cast<IComparable>();

因此,虽然这是有效的,因为string是引用类型:

List<string> strings = new List<string>();
IEnumerable<IComparable> comparables = strings;

...等效版本不适用于List<int>,您需要随身携带。

答案 1 :(得分:2)

它与泛型列表有一个共同的混淆,但基本上如果你概括它更有意义:

考虑这个设置:

public interface IA{
}

public class A : IA{
}

var listA = new List<A>();

以下行不起作用:

List<IA> listI = ListA;

基本上这是因为,即使A : IAList<I> does not : List<A> - 它们也是完全分开的类型。

虽然使用Cast方法,但您可以轻松地完成投射:

listI = ListA.Cast<IA>();

所以在你的情况下你可以做

test3 = t2.Cast<IComparable>();