Тернарные операторы в C#

С тернарным оператором можно сделать что-то вроде следующего (при условии, что Func1() и Func2() возвращают целое число:

int x = (x == y) ? Func1() : Func2();

Однако есть ли способ сделать то же самое, не возвращая значение? Например, что-то вроде (при условии, что Func1() и Func2() возвращают void):

(x == y) ? Func1() : Func2();

Я понимаю, что это можно сделать с помощью оператора if, мне просто интересно, есть ли способ сделать это так.


person Paul Michaels    schedule 04.05.2010    source источник
comment
Извините за придирки, но правильное имя — условный оператор msdn .microsoft.com/en-us/library/aa691313(VS.71).aspx   -  person Brian Rasmussen    schedule 04.05.2010
comment
@Brian: В той же статье иногда его также называют тернарным оператором. Так что на самом деле используются оба.   -  person Nelson Rothermel    schedule 04.05.2010
comment
@Nelson - в том смысле, что знак суммы также можно назвать бинарным оператором, а оператор приращения также можно назвать унарным оператором? Да... но это все еще неправильный способ назвать его, несмотря на то, что обычно это единственный известный тернарный оператор. (Есть ли еще? Хороший вопрос.)   -  person ANeves thinks SE is evil    schedule 04.05.2010
comment
Да, тернарные (и связанные с ними, такие как унарные, бинарные) — это более обобщенные имена. Таким образом, условный оператор является тернарным оператором (или тернарным оператором, если синтаксис языка не предусматривает другого), но тернарный оператор не обязательно является условным оператором. Я думаю, что в контексте языков программирования оба обычно понимаются как одно и то же. Если их больше, как вы сказали.   -  person Nelson Rothermel    schedule 04.05.2010
comment
Поиск в Google по запросам «тройной оператор C#» и «условный оператор C#» дал одинаковое количество результатов, поэтому кажется, что они оба используются примерно с одинаковой частотой.   -  person Nelson Rothermel    schedule 04.05.2010


Ответы (4)


Странно, но вы могли бы сделать

class Program
{
    private delegate void F();

    static void Main(string[] args)
    {
        ((1 == 1) ? new F(f1) : new F(f2))();
    }

    static void f1()
    {
        Console.WriteLine("1");
    }

    static void f2()
    { 
        Console.WriteLine("2");
    }
}
person Diego Pereyra    schedule 04.05.2010
comment
Это много дополнительной работы, чтобы избежать использования только if и else. Хороший фрагмент, однако. - person djdd87; 04.05.2010

Я так не думаю. Насколько я помню, тернарный оператор используется в контексте выражения, а не как инструкция. Компилятор должен знать тип выражения, а void на самом деле не является типом.

Вы можете попробовать определить функцию для этого:

void iif(bool condition, Action a, Action b)
{
    if (condition) a(); else b();
}

И тогда вы могли бы назвать это так:

iif(x > y, Func1, Func2);

Но это не делает ваш код яснее...

person Daren Thomas    schedule 04.05.2010

Если вы чувствуете себя уверенно, вы должны создать статический метод, единственной целью которого является поглощение выражения и «сделать его» оператором.

public static class Extension
{
    public static void Do(this Object x) { }
}

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

((x == y) ? Func1() : Func2()).Do(); 

Или, почти эквивалентным образом, написать статический метод (если класс, когда вы хотите использовать этот «ярлык», ограничен).

private static void Do(object item){ }

... и называя это таким образом

Do((x == y) ? Func1() : Func2());

Однако я настоятельно рекомендую не использовать этот «ярлык» по тем же причинам, которые уже были указаны авторами до меня.

person Erik Burigo    schedule 04.05.2010

Нет, потому что тернарный оператор — это выражение, а функции action/void — это операторы. Вы можете заставить их возвращать object, но я думаю, что блок if/else сделал бы намерение более ясным (т. е. действия выполняются для их побочных эффектов, а не для их значений).

person Lee    schedule 04.05.2010