模板错误的通用

Jos*_*osh 3 c# generics

我正在尝试创建模板化类的列表,将基类传递给模板.但是,似乎不允许这样做.有没有办法绕过这个限制,或者更恰当地重构我的代码?

这是一个抽象的例子:

using System;
using System.Collections.Generic;

namespace TempInherit
{
    abstract class Shape{}

    class Triangle : Shape{}
    class Square : Shape{}

    class ShapeHolder<T>{}

    class MainClass
    {
        public static void Main(string[] args)
        {
            // list of base class, add subclass - works
            List<Shape> shapes = new List<Shape>();
            shapes.Add(new Triangle());
            shapes.Add(new Square());

            // list of holders of base class, add holders of subclass - fails
            List<ShapeHolder<Shape>> shapeHolders = new List<ShapeHolder<Shape>>();
            shapeHolders.Add(new ShapeHolder<Triangle>());
            shapeHolders.Add(new ShapeHolder<Square>());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

产量:

错误CS1502:"System.Collections.Generic.List> .Add(TempInherit.ShapeHolder)"的最佳重载方法匹配具有一些无效参数(CS1502)(TempInherit)

错误CS1503:参数#1' cannot convert TempInherit.ShapeHolder'表达式以键入`TempInherit.ShapeHolder'(CS1503)(TempInherit)

Rap*_*aus 6

协方差问题:

您可以创建一个接口IShapeHolder<out T>,因为接口上的泛型参数可以是协变的(但不是类)

类似的东西

public class Shape
    {
    }
    public class Triangle : Shape
    {
    }
    public class Square : Shape
    {
    }
    //T generic parameter is covariant (out keyword)
    public interface IShapeHolder<out T> where T : Shape
    {
    }
    public class ShapeHolder<T>  : IShapeHolder<T> where T: Shape
    { 
    }
Run Code Online (Sandbox Code Playgroud)

然后,

var shapes = new List<Shape>();
shapes.Add(new Triangle());
shapes.Add(new Square());

// list of holders of base class, add holders of subclass - fails no more
var shapeHolders = new List<IShapeHolder<Shape>>();
shapeHolders.Add(new ShapeHolder<Triangle>());
shapeHolders.Add(new ShapeHolder<Square>());
Run Code Online (Sandbox Code Playgroud)

  • 提问者注意,这不允许从`shapeHolder`中检索项目.但这是设计意图,否则你可以将`Square`插入`ShapeHolder <Triangle>`,将其转换为`ShapeHolder <Shape>`. (2认同)