Variant and open generics IReadOnlyList

I'm trying to understand why a specific behavior regarding variant and generics in c# does not compile.

class Matrix<TLine> where TLine : ILine
{
    TLine[] _lines;

    IReadOnlyList<ILine> Lines { get { return _lines; } } //does not compile
    IReadOnlyList<TLine> Lines { get { return _lines; } } //compile
}

I can't understand why this does not work as :

  • _lines, being of type TLine[], implements IReadOnlyList<TLine>
  • IReadOnlyList<out T> is a variant generic interface, which means, as far as I understand, that anything implementing IReadOnlyList<TLine> can be used as a IReadOnlyList<ILine>

I feel that it must be because the type constraint is not taken into account, but I doubt it.

Jon Skeet
people
quotationmark

You just need to add the class constraint to TLine:

class Matrix<TLine> where TLine : class, ILine

This will ensure that TLine is a reference type - which then allows generic variance to work. Variance only works for reference types, because that way the CLR knows that the value of type TLine can be used as a value of type ILine without any boxing or other change in representation.

people

See more on this question at Stackoverflow