?: ?? Операторы вместо IF | ELSE


85
public string Source
{
    get
    {
        /*
        if ( Source == null ){
            return string . Empty;
        } else {
            return Source;
        }
        */
        return Source ?? string.Empty;
    }
    set
    {
        /*
        if ( Source == null ) {
            Source = string . Empty;
        } else {
            if ( Source == value ) {
                Source = Source;
            } else {
                Source = value;
            }
        }
        */
        Source == value ? Source : value ?? string.Empty;
        RaisePropertyChanged ( "Source" );
    }
}

Могу ли я использовать ?: ??операторы ТОЧНО как If / Else?


Мой вопрос:
Как написать следующее с помощью?: ?? операторы

[1]

if ( Source == null ){
    // Return Nothing
} else {
    return Source;
}

[2]

if ( Source == value ){
    // Do Nothing
} else {
    Source = value;
    RaisePropertyChanged ( "Source" );
} 

Вкратце : как ничего не делать, ничего не возвращать и выполнять несколько инструкций с ?: ??оператором?


1
Однако он не будет вести себя так же. Не используя условное ветвление if / else, вы безоговорочно (и без необходимости) переназначаете переменную каждый раз, когда к ней обращаетесь. Это может очень быстро испортиться, особенно если у вас многопоточный код. Просто не делай этого.
Джефф Меркадо

1
У вас будет бесконечный / рекурсивный вызов, если метод доступа get свойства Source возвращает свойство Source (его метод доступа get).
John K

1
В вашем первом фрагменте кода есть геттер свойств, который вызывает собственный метод установки , который, в свою очередь, рекурсивно вызывает собственный метод получения . Вы потеряли меня там, потому что ничего подобного не может сработать в этой области. Уточните свой вопрос и объясните, чего именно вы хотите достичь.
Frédéric Hamidi

Ничего не вернуть? Это VB. Вы пишете здесь C #.
Задача

@Task Я имею в виду, как это сделать, эта строка является комментарием к вопросу
Ахмед Гонейм

Ответы:


198

Для [1] вы не можете: эти операторы предназначены для возврата значения, а не для выполнения операций.

Выражение

a ? b : c

оценивается как bесли aистинно, и оценивается как cесли aложно.

Выражение

b ?? c

оценивается как bесли bне равно нулю и оценивается как cесли bравно нулю.

Если вы напишете

return a ? b : c;

или

return b ?? c;

они всегда что-то вернут.

Для [2] вы можете написать функцию, которая возвращает правильное значение, которое выполняет ваши «множественные операции», но это, вероятно, хуже, чем просто использование if/else.


41

Тернарный оператор ( ?:) не предназначен для потока управления , он предназначен только для условного присваивания . Если вам нужно контролировать ход вашей программы, используйте структуру управления, такую ​​как if/ else.


5
Я добавлю, что я видел, как люди использовали вложенные тернарные выражения вместо if / else, и это создает код, который трудно читать и отлаживать. Плохое моджо вокруг.
ckramer 01

4
Иногда вложенные тернарные операторы создают более читаемый код, если пробелы используются правильно.
правдивость 01

2
@truth: Да, я ничего не имею против вложенности ?:как таковой. Но у меня большая проблема с их использованием для потока управления, особенно вложенного потока управления!
Оливер Чарльзуорт

11

Ссылаясь на ?: Оператор (Справочник по C #)

Условный оператор (? :) возвращает одно из двух значений в зависимости от значения логического выражения. Ниже приводится синтаксис условного оператора.

Ссылаясь на ?? Оператор (Справочник по C #)

?? Оператор называется оператором объединения с нулевым значением и используется для определения значения по умолчанию для типов значений, допускающих значение NULL, а также для ссылочных типов. Он возвращает левый операнд, если он не равен нулю; в противном случае возвращается правильный операнд.

Это означает:

[Часть 1]

return source ?? String.Empty;

[Часть 2] не применяется ...


3
Это отличается от бездействия. Возвращает пустую строку.
правдивость 01

1
Конечно, но ОП просила не об этом. Я не виноват, что ОП попросил «ничего не вернуть» - что бы это ни значило.
правдивость 01

1
@trutheality: Никто не сказал, что это твоя вина .. Однако ОП не хотел ничего возвращать, и то, что я предоставил.
Akram Shahda

3

«Ничего не делать» действительно не работает?

если // Ничего не вернуть, вы на самом деле имеете в виду return null, тогда напишите

return Source;

если вы имеете в виду, игнорируйте кодовый путь, затем напишите

 if ( Source != null )
            {
                return Source;
            }
// source is null so continue on.

И напоследок

 if ( Source != value )
            { Source = value;
                RaisePropertyChanged ( "Source" );
            }

// nothing done.

3

Тернарный оператор ВОЗВРАЩАЕТ одно из двух значений. Или он может выполнить одно из двух операторов в зависимости от своего состояния, но это обычно не очень хорошая идея, поскольку может привести к непредвиденным побочным эффектам.

bar ? () : baz();

В этом случае () ничего не делает, а baz что-то делает. Но вы только сделали код менее понятным. Я бы выбрал более подробный код, более понятный и простой в обслуживании.

Кроме того, в этом нет никакого смысла:

var foo = bar ? () : baz();

Поскольку () не имеет типа возврата (он недействителен), а baz имеет тип возврата, который неизвестен в точке вызова в этом примере. Если они не согласны, компилятор громко пожалуется.


2

Если вас беспокоит многословность вашего кода, я бы написал это, а не пытался злоупотреблять выражениями.

if (Source == value) return;
Source = value;
RaisePropertyChanged("Source");

Я не злоупотребляю выражениями, я просто думаю!
Ахмед Гонейм

1

?: оператор маршрута. (полагаю, я правильно написал), и это просто в использовании. как в булевом предикате? iftrue: ifalse; Но у вас должно быть rvalue / lvalue, как в rvalue = predicate? iftrue: если ложно;

бывший int i = x < 7 ? x : 7;

если бы x было меньше 7, мне было бы назначено x, если бы не было 7.

вы также можете использовать его в качестве возврата, как в return x < 7 ? x : 7;

опять же, как и выше, это будет иметь тот же эффект.

Итак, Source = Source == value ? Source : string.Empty;я считаю, что это то, чего вы пытаетесь добиться.


6
Мне это нравится. Маршрут Оператор : это поможет вам получить от А до Б ... или от А до С ... в зависимости от А.
Рик Слэдки

Да, он имеет в виду тройной. Но правильное название - «условное».
Erick G. Hagstrom


0

Я не думаю, что вы можете его оператор и предположить, что он вернет один или другой. Это не замена оператора if else, хотя его можно использовать для этого в определенных случаях.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.