28

I'm interesting in some design choices of C# language. There is a rule in C# spec that allows to use method groups as the expressions of is operator:

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

Condition above is always false, as the specification says:

7.10.10 The is operator

If E is a method group or the null literal, of if the type of E is a reference type or a nullable type and the value of E is null, the result is false.

My questions: what is the purpose/point/reason of allowing to use the C# language element with no runtime representation in CLR like method groups inside the such "runtime" operator like is?

4

2 回答 2

21

允许在 CLR 中使用没有运行时表示的 C# 语言元素的目的/要点/原因是什么?

语言设计笔记档案没有提到为什么做出这个决定,所以任何对答案的猜测都是猜想。他们确实提到,如果“是”的结果可以静态确定为始终为真或为假,那么它会如此确定并产生警告。这似乎是合理的,这可能只是一个错误。

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

更新:

我刚刚检查了 C# 1.0 规范。它没有这种语言。它没有说明空值或方法组参数。当然,它没有说明方法组转换,因为在 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”突然开始返回真或成为错误将是一个重大更改。

进一步更新:

在调查这一点时,我学到了一些有趣的东西。(对我来说。)最初设计该功能时,设计是允许类型名称或 Type 对象作为“is”的右手参数。这个想法在 C# 1.0 发布之前就被放弃了。

于 2010-07-12T20:34:41.593 回答
3

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

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

例子

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

   if (o is Class1) {}
}

来自 MSDN:

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

  • 表达式不为空。
  • 表达式可以转换为类型。也就是说,(type)(expression) 形式的强制转换表达式将在不引发异常的情况下完成。有关详细信息,请参阅 7.6.6 转换表达式。

因此,您的示例错误的原因在于第二点,它必须可以转换为特定类型。

我希望我没有误解这个问题。

于 2010-07-12T20:27:19.450 回答