C# 类型是输出安全的还是输入安全的?

C# 类型是输出安全的还是输入安全的?,c#,variance,C#,Variance,在C#语言规范的方差安全部分,我第一次遇到了以下术语:输出安全、输入安全、输出不安全和输入不安全。我熟悉方差的概念(协方差和逆方差),它基本上是指使用一种类型来代替另一种类型 那么,输出或输入安全究竟意味着什么呢?我们在这里讨论的是泛型类型中的类型参数还是任何类型(引用或值)?规范的这一部分——您指的是C#4规范的第13.1.3.1节,可能您应该在问题的某个地方提到——是不幸的,我道歉。Mads和我的意思是好的,但我从来没有对规范的这一部分结果感到兴奋 我们试图为C#规范提供一个更直观、更容易理

在C#语言规范的方差安全部分,我第一次遇到了以下术语:输出安全、输入安全、输出不安全和输入不安全。我熟悉方差的概念(协方差和逆方差),它基本上是指使用一种类型来代替另一种类型

那么,输出或输入安全究竟意味着什么呢?我们在这里讨论的是泛型类型中的类型参数还是任何类型(引用或值)?

规范的这一部分——您指的是C#4规范的第13.1.3.1节,可能您应该在问题的某个地方提到——是不幸的,我道歉。Mads和我的意思是好的,但我从来没有对规范的这一部分结果感到兴奋

我们试图为C#规范提供一个更直观、更容易理解的“协变有效”、“反变有效”和“不变有效”的描述;最初的规范草案就是用这些术语编写的,这让人感到困惑。结果实际上并不容易理解,而且包含一些错误

我的建议是:如果您需要了解变体界面有效或无效的确切规则,那么您应该阅读我关于该主题的说明,如下所示:

这本质上是我在实现该特性时所做注释的注释转录。这些注释比规范中最后的文本更详细、更清晰

您可能还需要阅读CLI规范中的相关部分;我的笔记直接基于对它的透彻阅读

要真正回答您的问题:“输出不安全”和“输入不安全”背后的思想本质上是,如果您有:

interface I<in T>
{
  T M();
}
这违反了类型安全性,因此我们说
T
是“输出不安全的”,因此此接口无效,因为显然
T
用于输出位置。与“输入不安全”类似:

接口I
{
空隙M(T);
}

你可以制作一个带长颈鹿的
I
,把它转换成
I
,然后把一只老虎传给
M
,这是不安全的
T
输入不安全,因此在输入位置使用
T
的此接口无效

没有人能完全肯定这个问题如此合适。我建议看看类似于或可能是@walther的站点:这里的“方差”是指一般类型参数协方差,而不是标准偏差的平方。这是分类理论,不是统计学。就连我都能理解,把老虎交给长颈鹿是不安全的,至少对长颈鹿来说是不安全的。
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.
interface I<out T>
{
    void M(T t);
}