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

С троичния оператор е възможно да направите нещо като следното (ако приемем, че Func1() и Func2() връщат int:

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

Не, защото троичният оператор е израз, докато функциите за действие/недействителност са изрази. Бихте могли да ги накарате да върнат object, но мисля, че блок if/else би направил намерението много по-ясно (т.е. действията се изпълняват за техните странични ефекти вместо за техните стойности).

person Lee    schedule 04.05.2010