允许在CLR中没有运行时表示的C#语言元素(例如方法组)与“is”等“运行时”操作符一起使用的目的/点/原因是什么?
语言设计笔记档案没有提到为什么要做出这个决定,所以任何答案都只能是猜测。它们确实提到,如果“is”的结果可以静态确定始终为true或false,则应如此确定并产生警告。这似乎可能只是一个错误。
将本来应该是错误变成警告(或简单地允许它)最常见的原因是减轻自动生成代码程序的制造者的负担。但是,我在这里看不到真正引人注目的情景。
更新:
我刚刚查看了C#1.0规范。它没有这种语言。它没有关于null或方法组参数的任何说明。当然,它也没有关于方法组转换的说明,因为在C#1.0中没有隐式方法组转换;如果您想要将方法M转换为委托类型D,必须明确调用“new D(M)” 。
后一点是“M is D”返回false而不是true的理由。您不能合法地说“D d = M;”,那么为什么“M is D”应该为true呢?
当然,在C#2.0中,这就不那么有意义了,因为您可以说“D d = M;”。
我还刚刚问过其中一位参与“is”操作符设计的人,他没有记忆中决定这个问题的方式。他怀疑“is”操作符的最初设计是不给出任何错误,仅给出警告,并且规范中关于如何处理方法组和null等内容的所有文本都是事后添加的,基于编译器实际执行的操作,用于C# 2.0版本的规范。简而言之,这似乎是C# 1.0中一个设计漏洞,当规范更新为C# 2.0时被掩盖了。看起来这种特定的行为并不是被期望和故意实现的。
事实上,这个理论得到了加强,因为在C# 2.0中,当匿名方法用作"is"的参数时会产生错误。这样做不会造成破坏性的改变,但“M is D”突然返回true或产生错误会造成破坏性的改变。
进一步更新:
在调查时,我了解到了一些有趣的事情(对我而言)。当最初设计该功能时,设计是允许类型名称或Type对象作为“is”的右侧参数。然而,在C# 1.0发布之前,这个想法就被放弃了。
as
运算符的部分没有提到方法组。 - Tim RobinsonMain as Foo
总是null
。而Main as System.Action
也是null
,然而System.Action a = Main
是可以的。 - Tim Robinsonis
或as
运算符的第一个操作数不能是 lambda 表达式或匿名方法。 - SLaksMain as Action
会导致error CS0039: Cannot convert type 'method group' to 'System.Action' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion
,所以不,它不是null
。 - Jeppe Stig Nielsen