【问题标题】:Why are the methods groups allowed on the left-side of ‘is’ operator and how can this be used in practice?为什么“is”运算符左侧允许使用方法组,如何在实践中使用?
【发布时间】:2015-11-24 17:07:41
【问题描述】:

首先“方法组是一组通过成员查找产生的重载方法”。在我的示例中,我使用了一组具有 19 个重载的 Console.WriteLine 方法。

C# 语言规范中方法组的定义还指出:“方法组允许在调用表达式 (§7.6.5) 、委托创建表达式 (§7.6.10.5) 并且作为 is 运算符的左侧,可以隐式转换为兼容的委托类型(第 6.6 节)。”

我可以想到这个功能可能有用的一种场景:

Action<string> print = (Action<string>)Console.WriteLine;
print("Hello!");

if (Console.WriteLine is Action<string>) 
{
    Console.WriteLine("We're compatible!");
}

前几行表明我们可以将方法组Console.WriteLine“强制转换”为委托。实际发生的是“转换为兼容委托类型的隐式转换”,它创建一个委托实例,调用具有兼容签名的许多重载 Console.WriteLine 方法之一。

所以根据规范,我们可以使用上面提到的“is 运算符的左侧”功能来测试方法组是否与给定的委托类型兼容(存在隐式转换)。这是示例代码中的“if”语句中检查的内容。

令人惊讶的是,代码编译了,但给出了警告“给定的表达式永远不是提供的 ('System.Action') 类型”。所以看起来不会在运行时尝试检查方法组和委托类型的兼容性。

因此,我的问题:

  • 如果无法在运行时执行检查,为什么在“is”运算符左侧允许方法组?
  • 为什么这个结构会给出警告而不是编译错误?
  • 有没有在‘is’运算符左侧使用方法组的实际场景?
  • 这是为将来使用而保留的东西吗,即设想上面的代码有一天会起作用?

【问题讨论】:

  • @Eric Lippert 已经在“The C# Programming Language”一书中写道:“is 运算符左侧的方法组是合法的,这有点误导。结果is 的评估将始终为 false,即使方法组可转换为右侧的类型”。见books.google.co.il/…

标签: c# methods delegates


【解决方案1】:

规范 (4.0) 明确指出了这种特定情况:

7.10.10 is 运算符

[...] E is T 操作的结果,其中E 是一个表达式,T 是一个类型,是一个布尔值 [...]

到目前为止,一切都很好。规范继续:

如果E 是一个方法组[...],则结果为假。

鉴于此信息,让我们看看您的问题。

如果在运行时无法执行检查,为什么在“is”运算符左侧允许方法组?

规范允许这种操作。请参阅 Lippert's answer on another question 了解这是如何产生的。

为什么这个构造会给出警告而不是编译错误?

该构造在语法上是有效的,即使它总是评估为假。该警告只是为了让您知道您可能正在做一些意外的事情。

有没有在‘is’运算符左侧使用方法组的实际场景?

可能不会。也许如果你收到了一个object,它可能是一个方法组或者可能是其他东西,这个构造可能很有用。 (诚​​然,这是一个人为的例子,代表了一些严重有问题的做法。)

这是为将来使用而保留的东西,即设想上面的代码有一天会起作用吗?

没有。再次引用 Lippert 的话:“这 将是一个突破性的改变,让 'M 是 D' 突然开始返回 true 或成为一个错误。” [强调原文]

【讨论】:

  • 完美!感谢您提供指向 Eric Lippert 对此问题的评论的链接。如果我自己能找到它,我不会问这个问题。
猜你喜欢
  • 2016-03-13
  • 2010-11-08
  • 2012-10-30
  • 2011-07-17
  • 2017-05-09
  • 1970-01-01
  • 2014-12-03
  • 2018-03-27
  • 2021-02-15
相关资源
最近更新 更多