2010-04-28 76 views
8

當我們在C#4.0中定義接口時,我們可以將每個通用參數標記爲inout。如果我們試圖設置一個泛型參數並導致問題,編譯器會提出一個錯誤,而不允許我們這樣做。C#4.0中的協變和逆變推斷

問:

如果編譯器推斷的方法有哪些兩個covarianceout)和contravariancein)有效的用途,爲什麼我們必須標記接口,這樣的?僅僅讓我們像往常一樣定義接口是不夠的,當我們試圖在我們的客戶代碼中使用它們時,如果我們試圖以不安全的方式使用它們,會引發錯誤?

例子:

interface MyInterface<out T> { 
    T abracadabra(); 
} 
//works OK 

interface MyInterface2<in T> { 
    T abracadabra(); 
} 
//compiler raises an error. 
//This makes me think that the compiler is cappable 
//of understanding what situations might generate 
//run-time problems and then prohibits them. 

此外,

是不是什麼Java那樣在同樣的情況?從我記得,你只是做一些像

IMyInterface<? extends whatever> myInterface; //covariance 
IMyInterface<? super whatever> myInterface2; //contravariance 

或者我混合的東西?

感謝

回答

8

如果編譯器推斷的方法有哪些兩個協方差(出)和逆變(中)有效的用途,爲什麼我們必須標記接口,這樣的?

我不太確定我是否理解這個問題。我想你在問兩件事。

1)編譯器能否推導出方差註釋?

and

2)爲什麼C#不支持像Java那樣的調用站點差異?

這個問題的答案首先是:

interface IRezrov<V, W> 
{ 
    IRezrov<V, W> Rezrov(IRezrov<W, V> x); 
} 

我邀請你試圖推斷出所有可能的法律差異的註釋是對V和W你可能會得到一個驚喜。

如果你不能找出這種方法的唯一最好的方差註解,爲什麼你認爲編譯器可以?

更多的原因在這裏:

http://blogs.msdn.com/ericlippert/archive/2007/10/29/covariance-and-contravariance-in-c-part-seven-why-do-we-need-a-syntax-at-all.aspx

更普遍的:你的問題表示強詞奪理。廉價地檢查解決方案是否正確的能力在邏輯上並不意味着有一種便宜的方法來找到正確的解決方案。例如,計算機可以輕鬆驗證p * q == r對於兩千位素數p和q是真或假。這並不意味着很容易取r和找到p和q,使得等式得到滿足。編譯器可以輕鬆檢查方差註釋是正確還是不正確;這並不意味着它可以在潛在的數十億個可能的註釋中找到正確的方差註釋。

第二個答案是:C#不是Java。

+0

我認爲他的第二個問題更像是「C#的變異註釋與Java的通配符類型有什麼不同?」 – Gabe 2010-04-29 00:29:46

+1

@加貝:C#做*聲明網站*方差。 Java不會* call-site *方差。呼叫站點差異確實是一個有趣的想法,但讓我感到奇怪的是,根據特定站點上的使用方式,將類型變爲變體,而不是如何定義其行爲。 – 2010-04-29 00:37:18

+0

是的,我現在明白了Java使用的問題。它的好處是不需要將接口參數聲明爲in或out,但是現在有些客戶端可能會立即給它一些使用權,如果我計劃更新接口,那麼以後可能不會被使用。 – 2010-04-29 00:42:27

0

OK,這裏是答案,我問(從Eric的回答):http://blogs.msdn.com/ericlippert/archive/2007/10/29/covariance-and-contravariance-in-c-part-seven-why-do-we-need-a-syntax-at-all.aspx

首先,在我看來,方差 應該是東西,你 故意設計到您的 接口或代表。使其只是 開始發生而不受 用戶的控制,並且 也可以引入重大更改。 (對那些在以後的文章更 !)

這樣做自動地也意味着 作爲發展進程的推移和 方法添加到界面中, 方差接口可能會改變 意外。這可能在程序中的其他地方引入 意外和深遠的變化 。

我決定把它明確地放在這裏,因爲雖然他的鏈接確實有我的問題的答案,但帖子本身並沒有。