我有下一个课程:
public class EntityBase<T>
{
public T Id { get; set; }
}
它的实施者:
public class ClassA : EntityBase<Int32>
{
...
}
public class ClassB : EntityBase<Int64>
{
...
}
在不熟悉类的代码中 - ClassA
和ClassB
它只知道EntityBase&lt; ...&gt;的存在,我做了类似的事情:
// 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&lt;&gt;。有没有办法施展它? 任何进步都是如此。
答案 0 :(得分:2)
你出于明确原因不能这样做。我们假设这行代码将工作:
List<EntityBase<Int32>> listOfEntityBases = (List<EntityBase<Int32>>)obj;
这意味着在该行之后您可以执行以下操作
listOfEntityBases.Add(new EntityBase<Int32>());
但实际上这一行同时会将EntityBase<Int32>
对象添加到obj
类List<ClassA>
- 这绝对是 InvalidCast 。
因此,您无法在同一时间内将{strong>相同的变量声明为List<ClassA>
和List<EntityBase<Int32>>
。
虽然IEnumerable<T>
很容易被允许,因为无法为此类收集添加新值。
这就是为什么他们在泛型声明中有in
和out
。
答案 1 :(得分:0)
你不能这样做,因为:
IList<T>
和ICollection<T>
不是协变的。您可以在此处执行的唯一选项(制作列表副本除外)是IEnumerabe<T>
的投射:
var listOfEntityBases = (IEnumerable<EntityBase<Int32>>)obj;