Nic*_*Eye 8 c# methods delegates
首先,"方法组是由成员查找产生的一组重载方法".在我的例子中,我使用了Console.WriteLine19个重载的方法集.
C#语言规范中方法组的定义还指出:"在调用表达式(第7.6.5节)中允许使用方法组,在委托创建表达式(第7.6.10.5节)中使用方法组,并在左侧使用是一个运算符,可以隐式转换为兼容的委托类型(第6.6节)."
我可以想到这个功能可能有用的一个场景:
Action<string> print = (Action<string>)Console.WriteLine;
print("Hello!");
if (Console.WriteLine is Action<string>)
{
Console.WriteLine("We're compatible!");
}
Run Code Online (Sandbox Code Playgroud)
前几行显示我们可以将方法组" Console.WriteLine转换"为委托.实际发生的是"转换为兼容委托类型的隐式转换",它创建委托实例,调用Console.WriteLine具有兼容签名的许多重载方法之一.
因此,根据规范,我们可以使用上面提到的"运算符的左侧"功能来测试方法组是否与给定的委托类型兼容(存在隐式转换).这是在示例代码中的'if'语句中检查的内容.
令人惊讶的是,代码编译,但发出警告"给定的表达式永远不会提供('System.Action')类型".因此,似乎不会尝试在运行时检查方法组和委托类型的兼容性.
因此,我的问题:
规范 (4.0) 明确指出了这种特定情况:
\n\n\n7.10.10
\nis操作员[...] 运算的结果
\nE is T,其中E是表达式,T是类型,是布尔值 [...]
到目前为止,一切都很好。规范继续:
\n\n\n如果
\nE是方法组[...],则结果为 false。
有了这些信息,让我们看看您的问题。
\n\n\n如果无法在运行时执行检查,为什么 \xe2\x80\x98is\xe2\x80\x99 运算符的左侧允许使用方法组?
\n
该规范允许进行此操作。请参阅利珀特在另一个问题上的回答,了解这是如何发生的。
\n\n\n为什么这个构造会给出警告而不是编译错误?
\n
该构造在语法上是有效的,即使它总是评估为 false。该警告只是让您知道您可能正在做一些意想不到的事情。
\n\n\n是否有在 \xe2\x80\x98is\xe2\x80\x99 运算符左侧使用方法组的实际场景?
\n
可能不会。也许如果你传递了一个object可能是方法组或者可能是其他东西的东西,那么这个构造可能会很有用。(诚然,这是一个人为的例子,代表了一些严重可疑的做法。)
\n\n这是为将来使用保留的东西吗,即设想上面的代码有一天会起作用?
\n
不。再次引用 Lippert 的话“如果‘M is D’突然开始返回 true 或成为错误,这将是一个重大改变。” [原文强调]
\n