C#:泛型内没有投射?

时间:2009-04-19 13:18:01

标签: c# generics casting

虽然我可以将字符串向上转换为对象,但我无法将IList字符串向上转换为IList对象。怎么会?现在该怎么做才能将所有项目都复制到一个新的IList?

static void ThisWorks()
{
     IList<object> list = new List<object>();
     list.Add("I can add a string since string : object");
}

static void ThisDoesNotWork()
{
     // throws an invalid cast exception
     IList<object> list = (IList<object>) new List<string>(); 

     list.Add("I'm never getting here ... why?");
}

4 个答案:

答案 0 :(得分:7)

这是不可能的,因为泛型是不变的(从C#3.0开始)。

您可以使用以下方法解决问题:

var objectList = list.Cast<object>().ToList();

答案 1 :(得分:4)

这样看:香蕉是一种水果,一篮子香蕉不是一篮子水果,因为你可以在后者中加入橙子,但不是前者。您的List<string>具有比List<object>更强的约束。

施法应始终尊重Liskow。对于不允许改装的容器和迭代器,这种铸件是安全的,但是一旦可以改变,你就可以靠近薄冰滑冰。

答案 2 :(得分:4)

你问的内容基本上是逆变和协方差的问题。它是编程语言设计中的一个概念,它讨论了方法和集合在同一继承层次结构中对两个类的对象的行为方式。阅读Wikipedia article可能有助于将您的上述好奇心放在更大,更一般的视角中。

答案 3 :(得分:1)

string继承自object,但IList<string>不会从IList<object>继承它们不相关的类型,因此您无法在它们之间进行转换。

想想如果这样做会发生什么:

// THIS CODE DOES NOT WORK
IList<object> list = new List<string>(); // this doesn't compile
list.Add(5); // because this is perfectly valid on IList<object> but not on IList<string>