在 C# 中可以为类型参数添加方差注释,限制为值类型:
interface IFoo<in T> where T : struct
{
void Boo(T x);
}
如果方差注释在这种情况下完全没有意义,为什么编译器允许这样做?
为什么编译器允许这样做,因为方差注释在这种情况下完全没有意义?
这是编译器允许的,因为当我将方差规则添加到 C# 4.0 编译器时,我从未考虑过有人可能会尝试这样做。
编译器警告和错误是功能,为了实现某个功能,至少必须在发布编译器之前考虑到该功能。我没有这样做,因此从来没有机会辩论是否应该对这种情况发出警告。
既然你已经引起我的注意,问题是:应该它是一个功能吗?编译器是否应该针对这种情况产生警告(或错误)?
这是一个判断。我们会考虑的一些事情是:
代码是否是人们可能会输入的代码,认为它做了一些明智的事情? 人们希望不会;人们希望对类型系统有足够了解以制作接口变体的开发人员也知道变体仅适用于引用类型。但也许有些开发人员可能会输入此内容,认为它会起作用。至少这似乎并没有超出合理范围。这不是明显的设计。
代码是否明显错误? 是的,可能是这样。似乎不太可能有人故意想要编写一个看起来不同但实际上并非如此的界面。
等等。
我必须更多地考虑它,但乍一看,这实际上可能是添加到编译器中的一个不错的警告。我会与团队讨论,我们会考虑将其添加到 Roslyn 版本中。
谢谢你的主意!
它被允许只是因为它是合法的代码。这绝对没有坏处。是的,你不能使用逆变转换,但我没有看到这个问题。代码中的任何内容实际上都不会产生误导或隐藏一些扭曲的gotcha。
我只是认为编译器在检查方差有效性时不会检查
T
是否是值类型或引用类型。按理说,C# 团队假设任何使用通用接口差异的人都知道使用值类型这样做是没有意义的,并且在任何情况下都没有副作用。