Issue with casting List<ClassA> where ClassA:Generic&l
本文关键字:ClassA where Generic gt with casting lt Issue List | 更新日期: 2023-09-27 18:07:25
我有下一个类:
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<>。有办法抛掉它吗?
你不能这么做有明确的理由。让我们假设这行代码将工作:
List<EntityBase<Int32>> listOfEntityBases = (List<EntityBase<Int32>>)obj;
这意味着在这行之后你可以写
listOfEntityBases.Add(new EntityBase<Int32>());
,但实际上这一行在同一时间将EntityBase<Int32>
对象添加到List<ClassA>
类型的obj
-这绝对是InvalidCast。
因此,您不能同时将相同的变量声明为List<ClassA>
和List<EntityBase<Int32>>
。
但是,IEnumerable<T>
很容易允许,因为不能为这样的集合添加新值。
这就是为什么在泛型声明中有in
和out
你不能这样做,因为:
- c#中的
- 协方差不能用于类;
- 接口
IList<T>
和ICollection<T>
不协变。
你在这里唯一可以做的选择(除了复制一个列表)是转换到IEnumerabe<T>
:
var listOfEntityBases = (IEnumerable<EntityBase<Int32>>)obj;