Common template error

I am trying to compile a list of templated templates by passing a template to the base class. However, this does not seem to be allowed. Is there a way to work around this limitation, or to restructure my code in a more appropriate way?

Here's an abstract example:

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

      

What gives:

Bug CS1502: Better overloaded method match for `System.Collections.Generic.List> .Add (TempInherit.ShapeHolder) 'has some invalid arguments (CS1502) (TempInherit)

Bug CS1503: Expression #1' cannot convert

expression TempInherit.ShapeHolder for input of type 'TempInherit.ShapeHolder' (CS1503) (TempInherit)

+3


source to share


1 answer


covariance problem:

You can create an interface IShapeHolder<out T>

as shared parameters on interfaces can be covariant (but not for classes)

something like that



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

      

then

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

      

+6


source







All Articles