为什么在“is”运算符的左侧允许使用方法组,并且如何在实践中使用?

8
首先,“方法组是由成员查找产生的一组重载方法”。在我的例子中,我使用了具有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”运算符左侧的实际情况?
  • 这是为将来使用保留的内容吗?也就是说,上面的代码有一天会起作用吗?

1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - haim770
1个回答

1
规范(4.0)明确指出了这种情况:
7.10.10 is 运算符 [...] 表达式 E is T 的操作结果,其中 E 是一个表达式,T 是一个类型,是一个布尔值[...]。
到目前为止,一切都好。规范继续说明:
如果 E 是方法组[...],则结果为 false。
有了这些信息,让我们看看你的问题。
规范允许这种操作。请参见Lippert's answer on another question,了解它是如何产生的。
该结构在语法上是有效的,即使它总是评估为 false。警告只是为了让您知道可能会做一些意想不到的事情。

左侧使用方法组与‘is’运算符有什么实际的应用场景吗?

可能没有。也许如果你传递了一个可能是方法组或其他东西的object,这个构造可能会有用。(这显然是一个人为的例子,代表了一些严重可疑的做法。)

这是为未来使用保留的吗?即上面的代码预计有一天会起作用吗?

不是。再次引用Lippert的话,“使'M is D'突然开始返回true或成为错误将是一种破坏性的变化。”[原文中的强调]


您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Nicol Eye

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接