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

Pea*_*son 13 .net c# compiler-errors visual-studio

如果我有以下代码:

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));
}
Run Code Online (Sandbox Code Playgroud)

我在调用时遇到编译时错误Check(int, int):

错误CS0307:变量'int'不能与类型参数一起使用

我也得到这些错误:

错误CS0118:'b'是一个变量但是像类型
错误CS0118 一样使用:'a'是一个变量但是像一个类型一样使用

为什么会出现这些错误?代码有什么问题?

Eri*_*ert 26

对我来说这是一个美好的一天.我从没想过我会在野外看到其中的一个!我在编译器测试用例中只见过这个.

考虑以下程序片段:

F(G<A,B>(7));
Run Code Online (Sandbox Code Playgroud)

在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));
Run Code Online (Sandbox Code Playgroud)

作为对Check一个参数的调用:使用一个参数调用泛型方法a<b, a>.

正如您所发现的那样,解决方案很简单:只需添加更多括号即可将参数分隔为Check.

如果您有兴趣知道C#使用的确切规则来判断它何时是通用的,何时不是,它是:

如果可以将一系列标记解析为以type-argument-list结尾的简单名称,成员访问或指针成员访问,则会检查紧跟在closing> token之后的标记.如果是其中之一,( ) ] } : ; , . ? == != | ^则将type-argument-list保留为simple-name,member-access或pointer-member-access的一部分,并且丢弃令牌序列的任何其他可能的解析.否则,类型参数列表不被视为简单名称,成员访问或指针成员访问的一部分,即使没有其他可能的令牌序列解析.请注意,在解析namespace-or-type-name中的type-argument-list时,不应用这些规则.

相信我,必须实现这样的规则使得C#解析起来有点棘手.

  • *这对我来说是美好的一天......*让我想起这样的事情:*如果你看到一个人在寒冷的雨天走在街上微笑,那只能是一个预测已经成真的气象员*:)开个玩笑,好像往常一样! (7认同)