2017-01-06 41 views
14

我想了解爲什麼有關變種和泛型在C#中的特定行爲不編譯。變種和開放的泛型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 
} 

我不明白爲什麼這不能作爲工作:

  • _lines,是TLine[]類型,實現了IReadOnlyList<TLine>
  • IReadOnlyList<out T>是一個變體的通用接口,這意味着,只要據我所知,任何實施IReadOnlyList<TLine>可以用作IReadOnlyList<ILine>

我覺得它一定是因爲類型約束沒有考慮到,但我懷疑它。

+6

我認爲你需要給'TLine' - 'class Matrix 添加'class'約束,其中TLine:ILine,class'。如果'T'是一個值類型,'IReadOnlyList '的協方差不適用,因此您需要將'TLine'限制爲參考類型。 – Lee

+0

@李我也不知道,你應該把它作爲答案,因爲它解決了OP的問題;) – nozzleman

回答

13

你只需要到class約束添加到TLine

class Matrix<TLine> where TLine : class, ILine 

這將確保TLine是引用類型 - 然後讓通用方差工作。差異只有適用於參考類型,因爲CLR知道類型TLine的值可以用作ILine類型的值,而不會出現任何裝箱或其他表示形式的更改。