C#语言设计:`is`操作符内的方法组

我对C#语言的一些设计选择感兴趣。 C#规范中有一条规则允许使用方法组作为运算符的表达式:

 class Foo { static void Main() { if (Main is Foo) Main(); } } 

上述条件总是错误的,因为规范说:

7.10.10是运营商

如果E是方法组或空文字,如果E的类型是引用类型或可空类型且E的值为null,则结果为false。

我的问题:允许在CLR中使用没有运行时表示的C#语言元素的目的/点/原因是什么,就像这样的“运行时”运算符中的方法组一样?

允许在CLR中使用没有运行时表示的C#语言元素的目的/点/原因是什么,就像这样的“运行时”运算符中的方法组一样?

语言设计说明档案没有提到为什么做出这个决定,所以对答案的任何猜测都是猜想。 他们确实提到如果“是”的结果可以被静态地确定为永远是真或假,那么它就是如此确定并产生警告。 看起来似乎有点可能这只是一个错误。

将可能正确的错误转换为警告(或简单地允许它)的最常见原因是因为这减轻了自动生成代码的程序的生成者的负担。 但是,我在这里看不到真正令人信服的情况。

更新:

我刚检查了C#1.0规范。 它没有这种语言。 它没有说明null或方法组参数。 当然,它没有说明方法组转换,因为在C#1.0中没有隐含的方法组转换; 如果要将方法M转换为委托类型D,则必须显式调用“new D(M)”。

后一点是“M是D”返回虚假而非真实的理由; 你不能合法地说“D d = M;” 那么为什么“M是D”才是真的?

当然在C#2.0中这没有多大意义,因为你可以说“D d = M;” 在C#2.0中。

我还问过“is”操作员设计时出现的其中一个人,并且他无法以某种方式决定这个问题。 他的怀疑是“is”操作符的原始设计是不给出任何错误,只是警告,并且规范中的所有文本关于如何处理方法组和空值以及诸如事后添加的内容,对于C#2.0版本的规范,并基于编译器实际执行的操作。

简而言之,看起来这是C#1.0中的一个设计漏洞,当为C#2.0更新规范时,它已被涂抹。 看起来并不是这种特定的行为是有意和有意实施的。

当在C#2.0中用作“is”的参数时,匿名方法确实产生错误这一事实进一步强化了这一理论。 这样做不会是一个突破性的变化,但是如果“M is D”突然开始返回true或者是一个错误,那是一个突破性的变化。

进一步更新:

在研究这个时我学到了一些有趣的东西。 (对我来说。)当最初设计该特征时,设计是允许一个类型的名称, 或者一个Type对象作为“是”的右手参数。 在C#1.0出货之前,这个想法就被放弃了。

首先,一个方法不是一个类型,msdn明确说明如下:

is运算符用于检查对象的运行时类型是否与给定类型兼容

 public static void Test (object o) { Class1 a; if (o is Class1) {} } 

来自MSDN:

如果满足以下两个条件,则表达式的计算结果为true:

  • 表达式不为空。
  • 表达式可以转换为类型。 也就是说,forms(类型)(表达式)的强制转换表达式将在不抛出exception的情况下完成。 有关更多信息,请参见7.6.6转换表达式。

因此,您的示例在第二点上出现错误的原因,必须是可转换为特定类型。

我希望我没有错过理解这个问题。