2017-01-06 1 views
14

Ich versuche zu verstehen, warum ein bestimmtes Verhalten in Bezug auf Variante und Generics in C# nicht kompiliert.Variant und Open Generics IReadOnlyList

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

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

Ich kann nicht verstehen, warum dies nicht so funktioniert:

  • _lines, von TLine[] Typ ist, implementiert IReadOnlyList<TLine>
  • IReadOnlyList<out T> ist eine Variante generische Schnittstelle, was bedeutet, soweit Ich verstehe, dass alles, was IReadOnlyList<TLine> implementiert, als IReadOnlyList<ILine>
verwendet werden kann 0

Ich denke, dass es sein muss, weil die Typ-Einschränkung nicht berücksichtigt wird, aber ich bezweifle es.

+6

Ich denke, Sie müssen hinzufügen, eine 'Klasse' Einschränkung zu' TLine' - 'Klasse Matrix wo TLine: ILine, Klasse'. Die Kovarianz von 'IReadOnlyList ' gilt nicht, wenn 'T' ein Werttyp ist. Daher müssen Sie' TLine' als Referenztyp definieren. – Lee

+0

@Lee Ich wusste das auch nicht, du solltest dies als Antwort posten, da es das OP-Problem löst;) – nozzleman

Antwort

13

Sie müssen nur die class Einschränkung TLine hinzuzufügen:

class Matrix<TLine> where TLine : class, ILine 

Dadurch wird sichergestellt, dass TLine ein Referenztyp ist - die dann generische Varianz erlaubt zu arbeiten. Varianz nur funktioniert für Referenztypen, weil auf diese Weise der CLR weiß, dass der Wert des Typs TLine als Wert des Typs ILine ohne Boxing oder andere Änderung in der Darstellung verwendet werden kann.