В тернарном операторе C#, дающем ошибку: в качестве оператора могут использоваться только выражения присваивания, вызова, приращения, декремента и нового объекта

у меня есть следующие 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("%dn",isNumber10);
    return 0;
}

и этот код прекрасно работает.

теперь две программы точно такие же. Так почему же он работает в C, но не в C#?

3 ответов


тернарный оператор-это выражение, которое нельзя использовать в качестве оператора. Напротив, назначение-это выражение, которое can быть повышен до заявления. (следовательно, сообщение об ошибке, относящееся к выражениям" присвоение")

ты хочешь:

isNumber10 = number == 10 ? 1 : 0;

здесь вы используете ?: оператор как выражение, которое возвращает одно из двух значений (1 или 0), а затем присваивается переменной isNumber10.

чтобы немного повеселиться с этим, если вы создали этот метод:

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

и вы назвали это так:

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

он будет работать нормально. Проблема в том, что грамматика C# не позволяет большинству голых выражений жить в контексте, в котором значение выражения не потребляется. (Помните, что определяющее различие между выражением и утверждением заключается в том, что выражение создает выражение, а утверждение-нет) некоторые выражения разрешены вне этого руководства - например, вызов метода, возвращающего значение. Они становятся на техническом жаргоне"выражение заявлением". И полезно, что единственные кандидаты на выражения, которые могут быть повышены до операторов, точно определены сообщением об ошибке в заголовке вашего вопроса.

большинство из нас думают о заданиях как о высказываниях, но это более фундаментальное выражение. (возвращает значение, присвоенное при одновременно выполняя задание). Вот почему этот пустой вызов M фактически выполнит то, что вы хотите. (не очень четкий)

из вашего комментария, я добавлю этот комментарий как часть моего ответа:

единственная ваша ошибка заключается в том, что грамматика C# не позволяет этого. Конечно, может, но это не так. Мне напомнили о том, как оператор when в SQL является выражением (что означает, что вы можете сказать set i = когда x равно null тогда " a "else " B"), тогда как в C# такое использование было бы недопустимым (поскольку оператор switch не является выражением-он не может возвращать значение)


попробуйте это:

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

Console.WriteLine(isNumber10);

проблема в том, что грамматика 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;