这对我来说是美好的一天。我从没想过我会在野外看到其中之一!我只在编译器测试用例中见过这个。
考虑以下程序片段:
F(G<A,B>(7));
在 C# 1.0 中,这意味着“使用两个参数调用方法 F:G<A
and B>(7)
.
但 C# 2.0 添加了泛型。在 C# 2.0 中,这意味着“使用一个参数调用方法 F。该参数是对泛型方法的调用G<A, B>
有一个参数,7"。
这是一个突破性的改变。 C# 有一些启发式方法来尝试确保与此模式匹配的旧程序继续运行,但并非所有程序都可以。
C# 正在解释你的程序
Check(a < b, a > (flag ? c : b - 10));
作为呼叫Check
带一个参数:调用泛型方法a<b, a>
有一个论点。
正如您所发现的,解决方案很简单:只需放入更多括号来分隔要检查的参数。
如果您有兴趣了解 C# 用来区分何时是泛型、何时不是泛型的确切规则,则为:
如果可以将标记序列解析为以类型参数列表结尾的简单名称、成员访问或指针成员访问,则检查紧跟在结束 > 标记之后的标记。如果是其中之一( ) ] } : ; , . ? == != | ^
那么类型参数列表将作为简单名称、成员访问或指针成员访问的一部分保留,并且丢弃标记序列的任何其他可能的解析。否则,即使没有其他可能的标记序列解析,类型参数列表也不被视为简单名称、成员访问或指针成员访问的一部分。请注意,在解析命名空间或类型名称中的类型参数列表时,不应用这些规则。
必须实现这样的规则使得 C# 成为有点棘手来解析,相信我。