在C#三元运算符给出错误:只有赋值,调用,递增,递减和新对象表达式可用作语句

问题描述 投票:6回答:3

我有以下C#代码 -

using System;

class Program 
{
    static void Main()  
    {
        int number = 1;
        int isNumber10;
        (number==10)?(isNumber10=1):(isNumber10=0);
        Console.WriteLine(isNumber10);
    }
}

在编译它给我错误 -

错误CS0201:只能将赋值,调用,递增,递减和新对象表达式用作语句

C我习惯了以下代码 -

#include <stdio.h>
int main(){
    int isNumber10;
    int number = 1;
    (number==10)?(isNumber10=1):(isNumber10=0);
    printf("%d\n",isNumber10);
    return 0;
}

这段代码运行得很好。

现在,这两个程序完全相同。那么为什么它在C中运行而在C#中运行呢?

c# boolean ternary-operator
3个回答
11
投票

三元运算符是一个不能用作语句的表达式。相反,赋值是一个可以提升为语句的表达式。 (因此引用“赋值”表达式的错误消息)

你想要的是:

isNumber10 = number == 10 ? 1 : 0;

在这里,您使用?:运算符作为表达式,解析为两个值之一(10),然后分配给变量isNumber10

为了获得一点乐趣,如果你创建了这个方法:

public void M<T>(T value)
{
}

你称之为:

M((number==10)?(isNumber10=1):(isNumber10=0));

它会工作正常。问题只是C#语法不允许大多数裸表达式存在于不消耗表达式值的上下文中。 (请记住,表达式和语句之间的定义差异是表达式生成表达式,但语句不生成)某些表达式在本指南之外是允许的 - 例如,调用返回值的方法。这些在技术术语中成为“expression statement”。并且有用的是,可以提升为语句的表达式的唯一候选者正是由问题标题中的错误消息准确描述的。

我们大多数人都将作业视为陈述,但它更基本上是一种表达。 (它返回在同时执行分配时分配的值)。这就是为什么对M的空调实际上会实现你想要的。 (不是说它非常易读)

从您的评论中,我将添加此评论作为我的答案的一部分:

您的唯一错误是C#语法不允许的简单事实。它当然可以,但是,它没有。我想起了SQL中的when运算符是一个表达式(意思是你可以说set i =当x为null然后是'A'而不是'B')而在C#中这样的用法将是无效的(因为switch语句是不是表达式 - 它不能返回值)


1
投票

试试这个:

int number = 1;
int isNumber10 = (number == 10) ? 10 : 0;

Console.WriteLine(isNumber10);

0
投票

问题是C语法和C#语法不同。

我举一个简单的例子 -

约翰有个男人

在C中,以下陈述有效 -

(John has beard)?(Ask John to save):(ask John to not save);

在这里,约翰必须被引用两次。

以下声明也是有效的 -

Ask John to = (John has beard)? (save):(not save);

在这里约翰只被提到一次。

但在C#中只有以下声明有效 -

Ask John to = (John has beard)? (save):(not save);

就像给定代码中的那样 -

正确的C语法 -

(number==10)?(isNumber10=1):(isNumber10=0);

以及 -

isNumber10 = (number==10)? 1:0;

但在C#中只有以下语法是正确的 -

isNumber10 = (number==10)? 1:0;
© www.soinside.com 2019 - 2024. All rights reserved.