2013-04-23 62 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