I’m attempting to make a list of templated classes, passing in a base class to the template. It seems however, that this isn’t allowed. Is there a way to circumvent this restriction, or restructure my code more appropriately?
Here is 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>());
}
}
}
Which yields:
Error CS1502: The best overloaded method match for
`System.Collections.Generic.List>.Add(TempInherit.ShapeHolder)’
has some invalid arguments (CS1502) (TempInherit)Error CS1503: Argument
#1' cannot convertTempInherit.ShapeHolder’ expression to type
`TempInherit.ShapeHolder’ (CS1503) (TempInherit)
covariance problem :
You may create an interface
IShapeHolder<out T>, as generic parameters on interfaces can be covariant (but not on classes)something like that
then,