什么是输出安全或输入安全的类型?

本文关键字:安全 类型 输入 输出 什么 | 更新日期: 2023-09-27 18:10:29

我第一次接触这些术语:输出安全、输入安全、输出不安全和输入不安全是在c#语言规范的方差安全一节中。我熟悉方差(协方差和逆变方差)的概念,它基本上指的是用一种类型代替另一种类型。

那么输出或输入安全的真正含义是什么呢?我们在这里讨论的是泛型类型的类型参数还是任何类型(引用或值)?

什么是输出安全或输入安全的类型?

规范的这一部分——你指的是c# 4规范的第13.1.3.1节,也许你应该在你的问题中提到它——是不幸的,我道歉。Mads和我本意是好的,但我从来没有对这部分规范的结果感到兴奋。

我们试图为c#规范提出一个更直观、更易于理解的"协变有效"、"逆变有效"answers"不变有效"的描述;最初的规范草案是用这些术语写的,人们觉得很困惑。结果实际上并不容易理解,它包含一些错误。

我的建议是:如果你需要理解什么使一个变量接口有效或无效的精确规则那么你应该阅读我关于这个主题的笔记,在这里:

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

这基本上是我在实现该功能时所做的注释的注释转录。这些注释比说明书中的文本更详细,也更清晰。

您可能还需要阅读CLI规范中的相关章节;我的笔记是直接基于对它的全面阅读。

实际上回答你的问题:"输出不安全"answers"输入不安全"背后的想法本质上是,如果你有:

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作为输入位置的接口是无效的。