类型参数的C#variance注释,约束为值类型

时间:2012-02-19 21:12:00

标签: c# generics compiler-construction covariance contravariance

在C#中可以为方法参数添加方差注释,约束为值类型:

interface IFoo<in T> where T : struct
{
  void Boo(T x);
}

如果在这种情况下方差注释完全没有意义,为什么编译器允许这样做?

2 个答案:

答案 0 :(得分:36)

  

为什么编译器允许这样做,因为在这种情况下,方差注释完全没有意义?

编译器允许这样做,因为当我将方差规则添加到C#4.0编译器时,我甚至从未考虑过有人会尝试这样做。

编译器警告和错误是功能,并且为了实现某个功能,在发送编译器之前,必须至少考虑某些功能。 。我没有这样做,因此从来没有机会甚至辩论是否应该对这种情况发出警告。

既然你已经引起了我的注意,问题是:应该它是一个功能吗?编译器是否应该为此情况发出警告(或错误)?

这是一个判断电话。我们考虑的一些事情是:

  • 代码是否有人可能会认为它做了一些合理的事情?人们不希望;人们希望那些了解类型系统的开发人员能够创建一个接口变体也知道方差仅适用于引用类型。但也许有些开发人员可能会认为它会起作用。至少它似乎没有合理性。它没有明显的设计。

  • 代码明显错误?是的,它可能是。似乎不太可能有人故意想要编写一个看起来不同但实际上并非如此的界面。

等等。

我必须多考虑一下,但乍一看看起来这实际上可能是添加到编译器的一个不错的警告。我将与团队讨论,我们会考虑将其添加到Roslyn版本中。

感谢您的想法!

答案 1 :(得分:2)

这是允许的,因为它是合法代码。它完全没有害处。是的,你不能使用逆变换,但我没有看到问题。代码中的任何内容都不会产生误导或隐藏一些扭曲的 gotcha

我只是认为编译器在检查方差有效性时不会检查T值类型还是引用类型。按理说,C#团队认为使用通用接口方差的任何人都知道使用值类型这样做是没有意义的,并且在任何情况下都没有副作用。