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

时间:2016-09-23 21:20:22

标签: c# .net visual-studio compiler-errors

如果我有以下代码:

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:变量&#39; int&#39;不能与类型参数一起使用

我也遇到了这些错误:

  

错误CS0118:&#39; b&#39;是一个变量,但用作类型
  错误CS0118:&#39; a&#39;是一个变量但是像类型一样使用

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

1 个答案:

答案 0 :(得分:26)

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

考虑以下程序片段:

F(G<A,B>(7));

在C#1.0中,这意味着&#34;使用两个参数调用方法F:G<AB>(7)

但是C#2.0增加了泛型。在C#2.0中,这意味着&#34;用一个参数调用方法F.该参数是对泛型方法G<A, B>的调用,其中包含一个参数7&#34;。

这是一个突破性的变化。 C#有一些启发式方法可以确保符合此模式的旧程序继续工作,但并非所有程序都能正常工作。

C#正在解释你的程序

Check(a < b, a > (flag ? c : b - 10));

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

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

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

  

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

必须实现这样的规则才能让C#解析有点棘手,相信我。