3

テンプレートクラスのリストを作成し、基本クラスをテンプレートに渡そうとしています。ただし、これは許可されていないようです。この制限を回避する方法、またはコードをより適切に再構築する方法はありますか?

これが抽象的な例です:

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>());
        }
    }
}

どちらが得られますか:

エラーCS1502: `System.Collections.Generic.List> .Add(TempInherit.ShapeHolder)'に最適なオーバーロードされたメソッドの一致に、いくつかの無効な引数があります(CS1502)(TempInherit)

エラーCS1503:#1' cannot convert 「TempInherit.ShapeHolder」と入力する引数TempInherit.ShapeHolder'式(CS1503)(TempInherit)

4

1 に答える 1

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

それから、

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>());
于 2013-02-06T17:14:37.437 に答える