2013-04-26 111 views
1

以下總結了我對C#中差異的理解。我會很感激,如果你能告訴我我錯了什麼,因爲我讀了的文章Exact rules for variance validity作者:Eric Lippert,我無法理解它的大部分內容。類型差異

差異是這樣一種想法,即某種類型轉換(或投影,如Eric Lippert所說)類型轉換爲另一種類型可以保留賦值兼容性(協方差)或逆轉它(逆變),或者既不保留也不倒轉(不變)。 就是這樣;如果I是T中的協變變換,其中T是一組類型,那麼對於T中的任何T1和T2類型,如果T1可分配給T2,則I<T1>可分配給I<T2>。如果我是逆變的,結果將會恢復。如果我是不變的,那麼I<T1>既不可分配到I<T2>也不相反。

現在這對於一個類型是協變還是逆變意味着什麼?不是方差是類型投影的屬性,也不是類型本身的屬性。

這是什麼意思是一個泛型I<out T, in U> T是協變和U逆變?另外,逆變有效性逆變異有效性的方向是什麼,協變有效性逆變異有效性均值的方向?

+0

這是一個相當棘手的問題,在這裏的範圍似乎有點大。我會誠實地建議閱讀除埃裏克以外的更多文章,以瞭解co和逆變。 – Gjeltema 2013-04-26 00:25:57

回答

9

現在對於協變或逆變類型意味着什麼?不是方差是類型投影的屬性而不是類型本身的屬性?

是的,你是現貨。那麼,你幾乎現貨上。方差是類型關於類型上的給定關係的預測的屬性。

考慮這些語句:

  • 從引用類型T映射到鍵入IEnumerable<T>保留分配兼容性關係的方向上的投影,因此該投影是協變

  • 的投影從TIEnumerable<T>是T.

  • IEnumerable<T>協變是在T協變。

  • IEnumerable<T>是協變的。

我們說第四個;我們的意思是第一個。我們假設「IEnumerable<T>是協變的」,從上下文可以清楚地看到投影是什麼(從TIEnumerable<T>)以及保留關係是什麼(分配兼容性)。這樣說比較容易。

在你提到的這篇文章中,我甚至比這個開始更加sl;;我使用「協變」基本上意味着「可以以某種方式參與協變轉換」。然而,「協變有效」等定義是精確的。如果稱它爲「協變有效」使其難以理解,則稱之爲別的:

如果類型X是指針或非泛型或具有Frobby元素類型的數組,則稱其爲Frobby類型,或泛型類型,其中每個「in」類型參數是Blobby,每個「out」類型參數是Frobby,每個其他類型參數都是Frobby和Blobby。如果它是一個指針,非泛型或具有Blobby元素類型的數組,或者其中每個「in」類型參數是Frobby,每個「out」類型參數都是Blobby的泛型類型,則它被稱爲Blobby,並且每個其他類型的參數是Frobby和Blobby。

在那裏,我們根本沒有使用「covariant」或「contravariant」這兩個詞,我們對Frobby和Blobby都有精確的定義。

是什麼意思,一個泛型類型I<out T, in U>是協變的T和逆變上U

再次,這只是一個簡短的形式。第一部分意味着對於任何固定的U,參考類型TI<T, U>的投影是保留分配兼容性方向的投影。如果XY分配兼容且Z是任何類型,則I<X, Z>I<Y, Z>分配兼容。

同樣對於逆變部分,除了現在的T是固定的,並且投影反轉這個關係的方向。

另外,「逆變有效性逆轉變異有效性的方向」是什麼意思?

我的意思是,如果你讀了協有效性規則,比較它們的逆變有效性規則,你注意到的規則基本相同,只是一堆規則「背過身去」。這就是爲什麼我們稱之爲* contra *方差。

我在博客上有十幾篇關於方差的文章;如果此主題引起您的興趣,您可能需要從頭開始閱讀它們。

+3

Frobby和Blobby?這對自己的笑聲是值得的。 – 2013-04-26 05:19:50

+0

謝謝埃裏克!對於將高度複雜的信息渲染爲普通人能夠理解的簡化和結構化的術語和概念,您有這樣一種驚人的方式。 – 2013-04-26 20:01:33