编译错误:" Error CS0307:变量'不能与类型参数"一起使用



如果我有以下代码:

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<AB>(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#的有点棘手解析,相信我。

最新更新