如果我有以下代码:
private void Check(bool a, bool b)
{
}
private void Check(int a, int b, int c, bool flag)
{
Check(a < b, a > (flag ? c : b - 10));
}
我在调用Check(int, int)
时得到编译时错误:
错误CS0307:变量'int'不能用于类型参数
我也得到这些错误:
错误CS0118: 'b'是一个变量,但被用作类型
错误CS0118: 'a'是一个变量,但被用作类型
为什么会出现这些错误?代码有什么问题?
今天对我来说是伟大的一天。我从没想过会在野外看到它们!我只在编译器测试用例中见过这种情况。
考虑以下程序片段:
F(G<A,B>(7));
在c# 1.0中,这意味着"用两个参数调用方法F: G<A
和B>(7)
。
G<A, B>
的调用,带有一个参数,7"。
这是一个突破性的变化。c#有一些启发式方法来尝试确保匹配这种模式的旧程序继续工作,但并不是所有的程序都可以。
c#正在解释你的程序
Check(a < b, a > (flag ? c : b - 10));
作为对Check
的一个参数调用:对a<b, a>
的一个参数调用。
您的解决方案很简单,正如您所发现的:只需放入更多的括号来分隔要检查的参数。
如果你有兴趣知道c#使用的确切规则来判断它何时是泛型的,何时不是,它是:
如果标记序列可以解析为以类型参数列表结尾的简单名称、成员访问或指针成员访问,则检查紧接在结束>标记之后的标记。如果它是
( ) ] } : ; , . ? == != | ^
中的一个,则类型参数列表保留为简单名称、成员访问或指针成员访问的一部分,并丢弃任何其他可能的标记序列解析。否则,即使没有其他可能解析标记序列的方法,也不认为类型参数列表是简单名称、成员访问或指针成员访问的一部分。注意,在解析名称空间或类型名称中的类型参数列表时不应用这些规则。
必须实现这样的规则使c#的有点棘手解析,相信我。