Ничего не делать, когда достигнута другая сторона тернарного оператора?

Примечание. Я уже видел, как этот вопрос задавали раньше (a, b, c), но ни один из них не был на С#, ни полезно.

Предположим, я использую тернарный оператор ? : следующим образом (чтобы ничего не делать, когда имеет место false):

r==5? r=0 : <nothing> ;

Я получаю сообщение об ошибке. Помещение чего-то там, очевидно, решит проблему. Как я могу оставить другую сторону пустой, не создавая случайную пустую функцию?


person devRicher    schedule 14.12.2016    source источник
comment
Можете ли вы привести пример кода без псевдопсевдо?   -  person krillgar    schedule 14.12.2016
comment
Возможный дубликат ключевого слова "Ничего не делать" в C#?   -  person mammago    schedule 14.12.2016
comment
Какая польза от тернарного (условного) оператора, когда вы знаете, что не хотите ничего делать для одного случая?   -  person Steve    schedule 14.12.2016
comment
@krilgar r==5? r=0 : <nothing> ;   -  person devRicher    schedule 14.12.2016
comment
Если вы действительно хотите использовать условное выражение, вы можете использовать r = (r == 5 ? 0 : r), но вы должны просто использовать оператор if, т.е. if (r == 5) { r = 0; }   -  person Lee    schedule 14.12.2016
comment
@ Lee Это, наверное, лучший ответ. Спасибо.   -  person devRicher    schedule 14.12.2016


Ответы (5)


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

Foo() ? Bar() : Baz();

... потому что это не утверждение. Вы должны что-то сделать с результатом... например, когда вы обращаетесь к свойству.

Если вы хотите выполнять фрагмент кода только при выполнении определенного условия, оператор ?: не то, что вам нужно - вам нужен оператор if:

if (foo)
{
    bar();
}

Это так просто. Не пытайтесь превратить условный оператор во что-то, чем он не должен быть.

person Jon Skeet    schedule 14.12.2016
comment
Это все равно, что сказать, что вы либо хотите вызвать bar(). - person BoltClock; 14.12.2016
comment
Мой пример был немного неправильным, я обновил его до того, каким он должен быть сейчас. - person devRicher; 14.12.2016
comment
@devRicher: принцип остается прежним. - person BoltClock; 14.12.2016
comment
@devRicher: Это еще хуже, так как ваш второй операнд теперь имеет побочный эффект. Чего вы на самом деле пытаетесь достичь? Похоже, вы хотите if (r == 5) { r = 0; } . Если это то, что вы хотите, почему бы не использовать это? - person Jon Skeet; 14.12.2016
comment
@devRicher единственное решение этой проблемы r==5 ? r=0 : r; Даже в этом случае объективно лучше и читабельнее использовать if(r==5)r=0; - person Alfie Goodacre; 14.12.2016
comment
Ну, я пытаюсь просто сделать счетчик. Думаю, комментарий @AlfieGoodacre может помочь. - person devRicher; 14.12.2016
comment
@devRicher: Вы имеете в виду, что хотите, чтобы это было 0, 1, 2, 3, 4, 0, 1, 2, 3, 4 и т. Д.? Если это так, вы хотите: r = (r + 1) % 5;. Опять же, нет необходимости в условном операторе. - person Jon Skeet; 14.12.2016
comment
Такие язвительные комментарии, и даже ответ заканчивается какой-то язвительностью просто так. Как будто условный оператор — это какая-то святая функциональность, имеющая одну и только одну цель. я мог абсолютно точно представить, что использую его для чего-то вроде нулевой проверки. myObject != null ? myFunction(myObject);. Да, это не работает, я знаю. - person Enok82; 27.11.2020
comment
@ Enok82: Дело не в том, что это свято (и мне интересно, что в комментарии, возражающем против снарка, вы вставили больше снарка, чем я видел где-либо еще в этой ветке), но это предназначено для вычисления результата, а не для выполнения различных операторов. Хотя он мог быть разработан по-другому, я не вижу ничего плохого в том, что он не был разработан для того, что вы пытаетесь сделать. - person Jon Skeet; 27.11.2020

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

 if(Condition())Action();
person meJustAndrew    schedule 14.12.2016

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

r = 0

помимо присвоения r значения, также возвращает то же значение. Вы можете думать об этом как о функции. Вы можете вызвать функцию, которая, возможно, делает что-то еще, помимо возврата значения, которое вы можете использовать или не использовать.

Возьмем, к примеру:

int square(int n)
{
    // Now you can do other things here too. Maybe you do something with the UI in here:
    Console.WriteLine("Calculating...");
    // ^ Now thing of the above code as assigning a value to a variable.
    return n * n;
    // But after assigning the value, it also returns the value...
}

Итак, теперь предположим, что у вас может быть два варианта использования:

var x = square(2);
// -- OR --
square(2);

Обратите внимание, что оба оператора выводят 'Расчет...', но первый присваивает x значение 2 * 2 или 4.

Еще лучше, скажем, у нас есть функция:

int AssignValueToVariable(out int variable, int value)
{
    variable = value;
    return value;
}

Теперь функция явно избыточна, но давайте предположим, что мы можем использовать ее для лучшего понимания. Предположим, что это эквивалентно оператору присваивания =.

Тем не менее, мы можем вернуться к нашему сценарию. Тернарный оператор <condition> ? <true expression> : <false expression> принимает два выражения для возврата на основе указанного условия. Итак, когда вы пишете:

r == 5 ? r = 0 : r = 2; // Let's suppose the third operand to be r = 2

это эквивалентно:

r == 5 ? AssignValueToVariable(r, 0) : AssignValueToVariable(r, 2)

оба из которых по существу:

r == 5 ? 0 : 2

Это возвращает жесткое и быстрое правило, согласно которому операнды должны быть выражениями, поскольку все должно сводиться к выражению. Таким образом, вы можете получить своего рода эквивалент выражения "ничего", используя его значение по умолчанию.

Или, как упоминается в других ответах, используйте оператор if, прямо и просто:

if (r == 5)
    r = 0;

Экстраполируя предоставленный вами код, я предполагаю, что вы что-то делаете с оцененным выражением. Вы можете сохранить значение в отдельной переменной result и делать с ней что угодно:

int result;
if (r == 5)
    result = r = 0; // This sets the value of both result and r to 0

Теперь вы можете заменить result на ваше предыдущее выражение, которое вы хотели, то есть r == 5 ? r = 0 : <nothing> // Pseudo-code.

Надеюсь, поможет :)

person Fᴀʀʜᴀɴ Aɴᴀᴍ    schedule 15.12.2016

Теперь вы можете добиться этого с помощью Откажитесь от оператора, если вы действительно этого хотите.

public class Program
{
    public static void Main()
    {
        int r=5;
        _ = r==5 ? r=0 : 0;
        Console.WriteLine($"{r}");
        // outputs 0
    }
}

Теперь вы также можете сделать

_=Foo() ? Bar() : Baz();

Пока Bar и Baz возвращают один и тот же или конвертируемый тип.

person GilesDMiddleton    schedule 26.02.2019

Я могу предложить такой метод расширения:

public static T ChangeOn<T>(this T variable, bool condition, T newValue)
{
    return condition ? newValue : variable;
}

И используйте это так:

var result = r.ChangeOn(r == 5, 0);
//or: r = r.ChangeOn(r == 5, 0); for self change
person shA.t    schedule 18.12.2016
comment
Потому что многие намного лучше умеют быстро и точно читать логические символы, чем английское выражение, глядя на весь монитор кода. Синтаксис, который можно эффективно прочитать, является эффективным кодированием. Сюда входят носители английского языка. Все, что включает в себя множество круглых скобок, которые простираются выше и ниже строчных букв, может значительно увеличить визуальный шум по всему экрану. - person Chris; 27.09.2018