C# 语言设计:“is”运算符内的方法组

发布于 2024-09-08 19:52:09 字数 467 浏览 7 评论 0原文

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

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

上面的条件始终为 false,正如规范中所述:

7.10.10 is 运算符

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

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

┼── 2024-09-15 19:52:09

允许在 CLR 中使用没有运行时表示的 C# 语言元素(如“运行时”运算符内的方法组)的目的/要点/原因是什么?

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

将错误转变为警告(或简单地允许它)的最常见原因是因为这减轻了自动生成代码的程序制作者的负担。然而,我在这里并没有看到真正令人信服的场景。

更新:

我刚刚检查了 C# 1.0 规范。它里面没有这种语言。它没有说明任何有关空值或方法组参数的信息。当然,它没有提及方法组转换,因为在 C# 1.0 中没有隐式方法组转换;如果您想将方法 M 转换为委托类型 D,则必须显式调用“new D(M)”。

后一点是“M is D”返回 false 而不是 true 的理由;你不能合法地说“D d = M;”那么为什么“M is 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 对象作为“is”的右侧参数。不过,早在 C# 1.0 发布之前,这个想法就被放弃了。

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?

The language design notes archive make no mention of why this decision was made, so any guess at an answer will be a conjecture. They do mention that if the result of the "is" can be statically determined to always be true or false, that it be so determined and produce a warning. It seems plausible that this could simply be an error.

The most common reason for turning what could rightly be an error into a warning (or simply allowing it) is because that lessens the burden upon producers of programs that automatically generate code. However, I don't see a really compelling scenario here.

UPDATE:

I just checked the C# 1.0 specification. It does not have this language in it. It does not say anything about nulls or method group arguments. And of course it says nothing about method group conversions because in C# 1.0 there were no implicit method group conversions; you had to explicitly call "new D(M)" if you wanted to convert method M to delegate type D.

This latter point is justification for "M is D" returning false rather than true; You couldn't legally say "D d = M;" so why should "M is D" be true?

Of course in C# 2.0 this makes less sense, since you can say "D d = M;" in C# 2.0.

I also just asked one of the people present when the "is" operator was designed and he had no memory of ever deciding this question one way or the other. His suspicion was that the original design of the "is" operator was to not give any errors, only warnings, and that all the text in the spec about what to do with method groups and nulls and whatnot was added post-hoc, for the C# 2.0 version of the spec, and based on what the compiler actually did.

In short, it looks like this was a design hole in C# 1.0 that was papered over when the spec was updated for C# 2.0. It does not look like this specific behaviour was desired and deliberately implemented.

This theory is reinforced by the fact that anonymous methods do produce an error when used as an argument to "is" in C# 2.0. It would not be a breaking change to do so, but it would be a breaking change to make "M is D" suddenly start returning true or being an error.

FURTHER UPDATE:

While investigating this I learned something interesting. (To me.) When the feature was originally designed, the design was to allow either the name of a type, or a Type object as the right-hand argument to "is". That idea was abandoned well before C# 1.0 shipped though.

执笔绘流年 2024-09-15 19:52:09

首先,方法不是类型,msdn 明确指出:

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

示例

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

   if (o is Class1) {}
}

来自 MSDN:

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

  • 表达式不为 null。
  • 表达式可以转换为类型。也就是说,(类型)(表达式) 形式的强制转换表达式将完成,而不会引发异常。有关更多信息,请参阅 7.6.6 强制转换表达式。

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

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

First of all a method is not a type, msdn clearly states the following:

The is operator is used to check
whether the run-time type of an object
is compatible with a given type

Example

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

   if (o is Class1) {}
}

From MSDN:

An is expression evaluates to true if both of the following conditions are met:

  • expression is not null.
  • expression can be cast to type. That is, a cast expression of the form (type)(expression) will complete without throwing an exception. For more information, see 7.6.6 Cast expressions.

So the reason for your example being false lands on the second point, it has to be castable to a specific type.

I hope I did not missunderstand the question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文