为什么我不能运行以下代码?
static int num = 0;
static void Main(string[] args)
{
(num == 0) ? inc() : dec();
}
public static void inc()
{
num++;
}
public static void dec()
{
num--;
}
为什么C#不允许我使用三元“?:”运算符来检查条件然后相应地运行一个方法而不需要返回任何值?与此相同:
if (num == 0) inc();
else dec();
我不确定是否在其他语言中应用了相同的规则,例如Java,C ++等......
答案 0 :(得分:26)
为什么我不能运行以下代码?
因为您试图违反语言规范。条件运算符的操作数(C#4规范中的第7.14节)必须是表达式 - 并且返回类型为void
的方法的调用明确地“仅在语句表达式的上下文“(参见C#4规范的第7.1节)。
条件运算符的目的是提供一个表达式,该表达式是根据条件评估两个表达式之一的结果。 不根据条件执行两个操作之一。只需使用if
声明。
同样,条件运算符本身不构成有效语句,不仅仅是其他各种运算符:
a + b; // Invalid
x = a + b; // Valid, assignment expression can be an expression-statement
明确地从规范的第8.6节开始:
并非所有表达式都被允许作为语句。特别是,
x + y
和x == 1
等仅仅计算一个值(将被丢弃)的表达式不允许作为语句。
答案 1 :(得分:5)
Jon Skeet的答案完全记录了C#故意采用与C ++不同的路线。很难说为什么,但我会尝试,因为我相信这个问题也值得回答。
C#与C ++和Java共享大量语法。在这种情况下,选择了Java方式。这既涉及无法将2 + 2;
写为独立语句,也要求三元运算符返回值。
我相信这两个决定都与消除无法访问的代码有很大关系。 +
中的2 + 2
运算符可以被优化掉,因此如果它在代码中用于任何目的,那么该目的就不可靠了!理想情况下,静态分析(编译错误或警告)应该告诉您在这种情况下似乎存在语义问题,并强制您删除或重写无法访问的代码。
因此,表达式不再总是语句,需要为Java / C#重新定义C语法,表达式总是返回值,语句永远不会返回值。
现在?:
和if
- else
主要区别在于一个是表达式,一个是语句,至少在它们的典型用法中。所以重新定义的语法只是选择禁止无效的三元组,并为此目的推荐if
- else
。
答案 2 :(得分:2)
因为Ternary运算符根据布尔表达式赋值。它的基本C#规范。如果你的方法是void返回类型,那么最好是使用if - else或switch case。
int a = true ? 0 : 1; //Always works
true ? 0 : 1; //This will never work.
或者你的例子修改了一点。
static int num = 0;
static void Main(string[] args)
{
num = (num == 0) ? inc(num) : dec(num);
}
public static int inc(int lnum)
{
return lnum + 1;
}
public static int dec(int lnum)
{
return lnum - 1;
}
答案 3 :(得分:2)
条件运算符(?:)根据布尔表达式的值返回两个值中的一个。
它不会按照您在问题中描述的方式行事。 这里有三元运算符
上的更多字节http://msdn.microsoft.com/en-us/library/ty67wk28%28v=vs.80%29.aspx
答案 4 :(得分:2)
但是当它以这种方式使用时它会起作用:
static int num = 0;
static void Main(string[] args)
{
num = (num == 0) ? inc(num) : dec(num);
}
public static int inc(int number)
{
return number + 1;
}
public static int dec(int number)
{
return number - 1;
}