2

为什么我不能运行以下代码?

    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++ 等...

4

5 回答 5

26

为什么我不能运行以下代码?

因为您试图违反语言规范。条件运算符的操作数(C# 4 规范中的第 7.14 节)必须是表达式- 并且调用返回类型为 的void方法明确“仅在语句表达式的上下文中有效”(参见第 7.1 节C# 4 规范)。

条件运算符的目的是提供一个表达式,该表达式是基于条件评估两个表达式之一的结果。不是根据条件执行两个动作之一。只需使用一个if语句。

同样,条件运算符本身也不会形成有效的语句,就像其他各种运算符一样:

a + b; // Invalid
x = a + b; // Valid, assignment expression can be an expression-statement

明确来自规范的第 8.6 节:

并非所有表达式都允许作为语句。特别是,诸如x + yand之类x == 1的仅计算值(将被丢弃)的表达式不允许作为语句。

于 2012-05-28T12:09:39.433 回答
5

Jon Skeet 的回答完美地记录了 C# 故意走与 C++ 不同的路线。很难说为什么,但我会尝试,因为我相信这个问题也值得回答。

C# 与 C++ 和 Java 共享许多语法。在这种情况下,选择了 Java 方式。这既涉及无法编写2 + 2;为独立语句,也涉及要求三元运算符返回值。

我相信这两个决定都与消除无法访问的代码有很大关系。+运算符 in可以被优化掉,因此2 + 2如果它在代码中用于任何目的,那么该目的是不可靠的!静态分析(编译错误或警告)理想情况下应该告诉您在这种情况下似乎存在语义问题,并迫使您删除或重写无法访问的代码。

因此,表达式不再总是语句,需要为 Java/C# 重新定义 C 语法,表达式总是返回值,语句从不返回值。

现在?:if-else主要区别在于一个是表达式,一个是语句,至少在它们的典型用途上是这样。因此,重新定义的语法只是选择禁止 void 三元组并推荐if-else为此目的。

于 2012-05-28T12:47:43.307 回答
2

因为三元运算符基于布尔表达式赋值。它的基本 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;
}
于 2012-05-28T12:08:52.430 回答
2

条件运算符 (?:) 根据布尔表达式的值返回两个值之一。

它的行为方式与您在问题中描述的方式不同。这是关于三元运算符的更多字节

http://msdn.microsoft.com/en-us/library/ty67wk28%28v=vs.80%29.aspx

于 2012-05-28T12:10:32.020 回答
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;
}
于 2012-05-28T12:14:27.183 回答