如何将通用List <T>转换为基于接口的List <T>

Joh*_*ohn 7 .net c# generics interface type-conversion

我确信我遗漏了一些简单的东西,但是我试图将所有实现接口的强类型对象列表转换为该接口类型的列表.

下面是一个演示错误的示例:

public void ExampleCode(){
    List<Cube> cubes = new List<Cube>();
    List<Shape> allShapes;
    allShapes = cubes;//Syntax Error
    allShapes = (List<Shape>)cubes;//Syntax Error  
}

public class Cube : Shape
{
    public int ID { get; set; }
    public int Sides { get; set; }
}

public interface Shape
{
  int ID { get; set; }
  int Sides { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*kle 13

尝试:而不是像那样投射

allShapes = cubes.Cast<Shape>().ToList();
Run Code Online (Sandbox Code Playgroud)

你需要.NET 3.5.我相信Cast扩展方法可以在System.Linq中找到.

  • 注意,这会复制列表(虽然它包含引用的引用,但不会复制对象).这与投射列表对象本身不同. (2认同)

Ric*_*ard 6

你不能.因为List<T>并且ILIst<T>只支持不变类型参数.这可以T用于输入和输出参数(例如返回值).否则你可以打破类型安全.

其他接口(例如IEntumerable<T>)确实允许一些变化.

有关反对和共同变化的讨论,请参阅Eric Lippert的博客" 编码中的神奇冒险 ".特别是" 协方差和逆变 "标签.

编辑,刚刚添加到"C#常见问题"博客:Covariance和Contravariance FAQ