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>
{
     ...
}

在代码中,它不知道ClassAClassB类,它只知道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<>。有办法抛掉它吗?

Issue with casting List<ClassA> where ClassA:Generic&l

你不能这么做有明确的理由。让我们假设这行代码工作:

 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>很容易允许,因为不能为这样的集合添加新值。

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

你不能这样做,因为:

    c#中的
  • 协方差不能用于类;
  • 接口IList<T>ICollection<T>不协变。

你在这里唯一可以做的选择(除了复制一个列表)是转换到IEnumerabe<T>:

var listOfEntityBases = (IEnumerable<EntityBase<Int32>>)obj;