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)
source to share
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>());
source to share