2013-04-23 113 views
4

我在C#語言規範的差異安全部分中第一次遇到了輸出安全,輸入安全,輸出不安全和輸入不安全的術語。我熟悉方差的概念(協方差和反變量),它基本上是指用一種類型代替另一種類型。輸入安全或輸入安全的類型是什麼意思?

那麼輸出或輸入安全究竟意味着什麼?我們在這裏討論的是泛型類型中的類型參數還是任何類型(引用或值)?

+1

Nooot完全肯定這個問題適合SO。我建議看看像http://programmers.stackexchange.com/或http://stats.stackexchange.com/或http://stats.stackexchange.com/ – walther 2013-04-23 22:48:14

+3

@walther:「方差」這裏的意思是*泛型類型參數協方差*,而不是*標準差的平方*。這是類別理論,而不是統計。 – 2013-04-23 23:17:49

回答

11

這部分規範 - 你指的是C#4規範的第13.1.3.1節,或許你應該在你的問題的某處提及 - 這是不幸的,我很抱歉。 Mads和我的意思很好,但我從未對這部分規範如何結果感到興奮。我們試圖爲C#規範提供一個更直觀,更易於理解的「協變有效」,「反向有效」和「不變有效」的描述;原始草案規範是用這些術語編寫的,人們發現這些術語令人困惑。結果實際上並不容易理解,並且包含一些錯誤。

我的建議是:如果您需要了解精確的規則是什麼讓一個變種接口有效或無效那麼你應該看過我關於這個問題的注意事項,其現在的位置:

http://blogs.msdn.com/b/ericlippert/archive/2009/12/03/exact-rules-for-variance-validity.aspx

那基本上是我在實現該功能時所做註釋的註釋轉錄。這些筆記比規範中最後的文字更詳細,希望更清晰。

您可能還想閱讀CLI規範中的相關部分;我的筆記直接基於對其的全面閱讀。

要真正回答你的問題:背後的「輸出不安全」和「不安全輸入」的概念本質上是,如果你有:

interface I<in T> 
{ 
    T M(); 
} 

然後T不能安全地在輸出位置使用。假設我們允許這樣做;這樣做違反了類型安全:

class C : I<Animal> 
{ public Animal M() { return new Giraffe(); } } 
... 
I<Animal> ia = new C<Animal>(); 
I<Tiger> it = ia; // Contravariant! 
Tiger t = it.M(); // We just assigned a giraffe to a variable of type tiger. 

這違反了類型安全,所以我們說T是「輸出不安全的」,因此,這個接口是無效的,因爲說白了T是在輸出位置使用。同樣,對於「輸入不安全」:

interface I<out T> 
{ 
    void M(T t); 
} 

你可以做一個I<Giraffe>,需要一個長頸鹿,將其轉換爲I<Animal>,並在老虎傳遞給M,這是不是安全的。 T是輸入不安全的,因此此接口在輸入位置使用T無效。

+6

即使我能理解,把老虎傳給長頸鹿也是不安全的,至少對於長頸鹿來說是不安全的。 – RenniePet 2013-04-23 23:32:15

+0

讚賞Eric。 – 2013-04-24 02:28:14