2

我有下一节课:

public class EntityBase<T>
{
    public T Id { get; set; }

}

它的实施者:

public class ClassA : EntityBase<Int32>
{
     ...
}

public class ClassB : EntityBase<Int64>
{
     ...
}

ClassA在代码中,它不知道类 -ClassB它只知道 EntityBase<...> 的存在,我做了这样的事情:

     // Here for sure I get the list of `ClassA`
     object obj = GetSomeHowListOfClassA();
     List<EntityBase<Int32>> listOfEntityBases = (List<EntityBase<Int32>>)obj;

我得到了错误:

Unable to cast object of type 'System.Collections.Generic.List`1[...ClassA]' to type 'System.Collections.Generic.List`1[...EntityBase`1[System.Int32]]'.

我这样修复它:

var listOfEntityBases = new List<EntityBase<Int32>>(obj);

但我不喜欢这种方式,因为我正在创建新的 List<>。有没有办法投呢?感谢任何预付款。

4

2 回答 2

2

您不能出于明确的原因这样做。让我们假设这行代码可以工作:

 List<EntityBase<Int32>> listOfEntityBases = (List<EntityBase<Int32>>)obj;

这意味着在该行之后,您可以说以下

listOfEntityBases.Add(new EntityBase<Int32>());

但实际上这一行同时会将EntityBase<Int32>对象添加到您obj的类型中List<ClassA>- 这绝对是InvalidCast

因此,您不能同时声明与和相同的变量。List<ClassA>List<EntityBase<Int32>>

虽然,它很容易被允许,IEnumerable<T>因为您不能为此类集合添加新值。

这就是为什么他们有inout在泛型声明中。

于 2013-04-04T10:43:47.710 回答
0

你不能这样做,因为:

  • C# 中的协方差不适用于类;
  • 接口IList<T>并且ICollection<T>不是协变的。

您可以在此处执行的唯一选项(制作列表副本除外)是转换为IEnumerabe<T>

var listOfEntityBases = (IEnumerable<EntityBase<Int32>>)obj;
于 2013-04-04T10:43:38.037 回答