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

Posted

技术标签:

【中文标题】在 C# 三元运算符中给出错误:只有赋值、调用、递增、递减和新对象表达式可以用作语句【英文标题】:In C# ternary operator giving error: Only assignment, call, increment, decrement, and new object expressions can be used as a statement 【发布时间】:2018-06-03 15:19:45 【问题描述】:

我有以下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# 不是 C,在大多数情况下甚至不接近。 我会让帖子看起来很漂亮 【参考方案1】:

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

你想要的是:

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 = when x is null then 'A' else 'B'),而在 C# 中这样的用法是无效的(因为 switch 语句是不是表达式——它不能返回值)

【讨论】:

但在我的代码中,我正在检查条件 - (number==10)?如果为真则陈述为(isNumber10=1),如果为假则陈述为(isNumber10=0),这种方法哪里错了? @puregeek 也许去read the docs,可能会是一个更好的起点。 @DavidG 我读过,但请向我解释一下,我的方法中的语法错误在哪里?首先我检查条件,如果为真我做某事,如果为假我做某事 @puregeek 您唯一的错误是 C# 语法不允许这样做的简单事实。它当然可以,但是,它不能。我想起了 SQL 中的 when 运算符是一个表达式(意思是你可以说 set i = when x is null then 'A' else 'B'),而在 C# 中这样的用法是无效的(因为 switch 语句不是一个表达式——它不能返回一个值) @KirkWoll 请将此评论作为答案,因为没有一个答案是令人满意的【参考方案2】:

问题是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;

【讨论】:

【参考方案3】:

试试这个:

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

Console.WriteLine(isNumber10);

【讨论】:

我知道这个方法,但是两种方法都应该是正确的,为什么我的方法不正确? 这是因为你把这个int isNumber10; 的结束标签,而不是; 必须是= 一定是这个样子int isNumber10=(number == 10) ? (isNumber10 = 1) : (isNumber10 = 0);,但是在编程中这不是一个好习惯,因为它是分配空间。正确的方法是int isNumber10 = number == 10 ? 10 : 0; 好的,但是在我的陈述中,为什么在评估条件后,真假部分没有得到执行? 执行时尝试在末尾添加Console.ReadLine();

以上是关于在 C# 三元运算符中给出错误:只有赋值、调用、递增、递减和新对象表达式可以用作语句的主要内容,如果未能解决你的问题,请参考以下文章

即使在三元运算符中给出的左值很好,赋值语句也会出错

在 C# 中创建元组时编译错误,没有括号包围三元运算符

Perl 三元条件运算符中的赋值问题

右侧的三元/空合并运算符和赋值表达式?

C# - 为啥我不能在字符串中使用三元运算符? [复制]

C#错误CS0201:只有赋值、调用、递增、递减和新对象表达式可以作为语句使用