Тернарный оператор '? :'
От: _ichensky Европа https://github.com/ichensky
Дата: 28.11.15 20:17
Оценка:
Здравствуйте,
Используете ли вы тернарный оператор?
1. Какой вариант бы вы выбрали при написании кода 1.2.3 или 4?
2. Если выбирать между вариантами 1 и 2 и вы используете тернарный оператор, какой?
3. Если выбирать между вариантами 3 и 4, какой?

1. 
return a == 0
    ? func(a);
    : func(a + 100500);

2.  
return func(a == 0 ? a : a + 100500);

3. 
if(a == 0) 
{ 
    return func(a); 
}
return func(a + 100500);

4.
int b; 
if(a == 0) 
{ 
    b = func(a); 
}
else 
{
    b = func(a + 100500);
}
return b;


Если бы я писал код то выбрал второй варинт если бы 'a == 0' и 'a + 100500'
были достаточно короткими в строке, иначе — первый.
Если бы предполагал что в будущем может появиться еще какое-то условие, напр.
if(a == 2) {return (-1);} то выбрал бы третий вариант.
Четрвертый вариант мне не нравиться потому что протягивает переменную(или объект)
через все тело функции и создает код из кучи вложенных if-else, если можно вернуть
переменную сразу, как в варианте 3, то предпочту вариант 3.
Підтримати Україну у боротьбі з країною-терористом.

https://prytulafoundation.org/
https://u24.gov.ua/

Слава Збройним Силам України!!! Героям слава!!!
Re: Тернарный оператор '? :'
От: Sinix  
Дата: 28.11.15 21:10
Оценка: 2 (1) +4
Здравствуйте, _ichensky, Вы писали:

_>2. Если выбирать между вариантами 1 и 2 и вы используете тернарный оператор, какой?


Все неправильные
var x = a == 0 ? a : a + 100500:
return func(x);

Разделять ответственности надо.

Если func в обоих ветках используется одинаковый чисто по совпадению, то if однозначно. Разные ответственности — разные выражения.

_>3. Если выбирать между вариантами 3 и 4, какой?

if ... return в шарпе используется в основном для обработки частных случаев, чтобы упростить основное тело метода. Если код большой, то лучше if-else использовать. И код легче читается, и рефакторится проще.

Опять-таки см. выше про разделение ответственностей, позволяет избавиться от большинства "можно и так и так".
Re: Тернарный оператор '? :'
От: xy012111  
Дата: 28.11.15 21:11
Оценка: 38 (1) +2
Здравствуйте, _ichensky, Вы писали:

_>Используете ли вы тернарный оператор?


Постоянно для подобных вещей.

_>1. Какой вариант бы вы выбрали при написании кода 1.2.3 или 4?

_>2. Если выбирать между вариантами 1 и 2 и вы используете тернарный оператор, какой?

var argument = a == 0 ? a : a + 100500;
return func(argument);


_>3. Если выбирать между вариантами 3 и 4, какой?


if(a == 0) { 
  return func(a); 
} else {
  return func(a + 100500);
}


P.S. И, да, раз уж у вас тег [cs] для кода: в шарпе этот оператор называется Conditional operator. Вот пара слов от маэстро по этому поводу: What’s the difference between ternary and tertiary?
Отредактировано 28.11.2015 21:15 xy012111 . Предыдущая версия .
Re: Тернарный оператор '? :'
От: Don Reba Канада https://stackoverflow.com/users/49329/don-reba
Дата: 29.11.15 01:37
Оценка:
Это как спросить, какой из синонимов слова выбор я использую при письме. Зависит от намерения.
Ce n'est que pour vous dire ce que je vous dis.
Re: Тернарный оператор '? :'
От: Kolesiki  
Дата: 29.11.15 01:52
Оценка:
Здравствуйте, _ichensky, Вы писали:

Обычно пишу как в варианте 2 (не так сложно понять), а если условие добавляется, то вполне можно обойтись и так:

return a == 0 ?
    func(a) :
    (b > 7 ?
        func(a + 100500) :
        func(z - 20));
Re: Тернарный оператор '? :'
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 29.11.15 08:31
Оценка:
Здравствуйте, _ichensky, Вы писали:

_>2. Если выбирать между вариантами 1 и 2 и вы используете тернарный оператор, какой?


var delta = a == 0 ? 0 : 100500;
return func(a + delta);


_>3. Если выбирать между вариантами 3 и 4, какой?


Имхо, не смотрится, но возможет и такой вариант:

var delta = 100500; // Main line
if (a == 0) // Exceptional case
{
    delta = 0;
}
return func(a + delta);


Вообще 3 и 4 выглядят размазанно. Если код алгоритмический, где значения часто выбираются исходя из подобных условий, то в нём легко бўдет запутаться.
Re: Тернарный оператор '? :'
От: Doc Россия http://andrey.moveax.ru
Дата: 30.11.15 02:06
Оценка: +1
Здравствуйте, _ichensky, Вы писали:

_>Используете ли вы тернарный оператор?


Да

_>1. Какой вариант бы вы выбрали при написании кода 1.2.3 или 4?

_>2. Если выбирать между вариантами 1 и 2 и вы используете тернарный оператор, какой?
_>3. Если выбирать между вариантами 3 и 4, какой?

Из этих никакой.

Во-первых, как уже отметили, в операторе будет не вызов функции, а выбор значения параметра.
Если выражение получается коротким, то
int someParameter = a != 0 ? a : 100500;
this.DoSomething(someParameter);


в противном случае напишу:

int someParameter = a != 0 ?
    callToFunctionWithVeryLongNameOrSomeLinqHere1(a) :
    callToOtherFunctionWithVeryLongNameOrSomeOtherLinqHere(a);
this.DoSomething(someParameter);



Во-вторых, если же надо if (например по стандартам для кода), то будет вот такой вариант
int b; 
if(a != 0) 
    b = a); 
else 
    b = 100500;

int result = func(b);
return result;


Тут смысл в том, что чем меньше в коде return тем проще его читать (хотя конечно число вложенных блоков тоже надо учитывать, но в данном случае оно одинаково).
Re[2]: А зачем тут var
От: Doc Россия http://andrey.moveax.ru
Дата: 30.11.15 02:12
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Все неправильные

S>
S>var x = a == 0 ? a : a + 100500:
S>return func(x);
S>

S>Разделять ответственности надо.

Чуть-чуть офтопика. А оправдано ли тут использование var? Далеко не факт что результат будет int.
Все чаще встречаю var где попало. Т.е. его проще писать. Мне кажется var должно быть только там, где тип ясен при чтении или в принципе не известен. Например:
var someInstance = new SomeClass();

или
var result =  someData.Select(x => new { Id = x.ArticleId, Content = x.Content })
    .ToArray();
Re: все зависит от контекста
От: bazis1 Канада  
Дата: 30.11.15 03:51
Оценка: +1 :)
Здравствуйте, _ichensky, Вы писали:

ИМХО, нет ничего глупее, чем пытаться вывести универсальные правила для частных случаев типа этого. Я даже работал в команде, которая этим занималась, но она за год не написала не единой новой функции или класса — все время уходило на обсуждение правил

вообще, я обычно стараюсь писать код, чтобы:
а) максимизировать читаемость. т.е. понимание, что код делает и зачем это делается
б) максмизировать лаконичность не в ущерб первому пункту

исходя из этих 2 правил можно найти пример для почти каждого из вариантов:
1.
return FormatByteCount(time == 0 ? 0 : bytes / time);

Довольно очевидно, что мы уходим от деления на 0. Поэтому можно записать лаконично.

2.
if (value > 1024)
    return HandleSpecialCaseA(value);
if (value < 10)
    return HandleSpecialCaseB(value);

return HandleNormalCase(value);

Тут сразу читается паттерн "сначала частные случаи, потом общий". Удобно добавлять проверки на новые случаи.

3.
int result;
if (something)
    b = func1();
else if (something_else)
{
    if (subcase)
        b = func2();
    else
        b = func3();
}
else
{
    b = func4();
}
return b;

Здесь читается паттерн "все случаи — частные", но отсутвтвие return, ИМХО, оправдано только если в конце с b делается что-то общее, не зависящее от условий.
Re[3]: А зачем тут var
От: Sinix  
Дата: 30.11.15 06:10
Оценка:
Здравствуйте, Doc, Вы писали:

Doc>Чуть-чуть офтопика. А оправдано ли тут использование var? Далеко не факт что результат будет int.

Это от команды зависит.

Обычно соглашение — var по-умолчанию, тип указываем там, где он явно нужен. Иногда добавляется оччень здравое требование "встроенные типы тоже явно указываем", но тогда точно надо не полениться и сделать свою проверку, благо что с рослином тут дел на полчаса.

Doc>Все чаще встречаю var где попало. Т.е. его проще писать. Мне кажется var должно быть только там, где тип ясен при чтении или в принципе не известен. Например:

Ну... можно, но смысл? Надо изобретать какие-то чёткие критерии, иначе код превратится в дикую мешанину: половина var, половина — с явным указанием типов. Лучше уж выбрать что-то одно, чем зоопарк держать.

Есть конечно исключения типа mission-critical кода, но это именно исключения
Re: Второй
От: igor-booch Россия  
Дата: 30.11.15 09:29
Оценка: :)
Я думаю будет быстрее работать
http://rsdn.ru/Info/rules.xml
Re[4]: А зачем тут var
От: Doc Россия http://andrey.moveax.ru
Дата: 30.11.15 09:40
Оценка: +1
Здравствуйте, Sinix, Вы писали:

S>Это от команды зависит.


Ну когда есть стили кодирования, то и вопроса нет. Я больше про собственное мнение (ну или если от решения сам стиль зависит).

S>Ну... можно, но смысл? Надо изобретать какие-то чёткие критерии, иначе код превратится в дикую мешанину: половина var, половина — с явным указанием типов. Лучше уж выбрать что-то одно, чем зоопарк держать.


А чем код с избытком var не зоопарк? Хотя кончено дело привычки.

Основные случае, когда тип точно известен и указан явно, не так и сложно перечислить
1) new SomeClass()
2) generic методы c явным указанием типа, когда он же и является типом результата: var x = Foo<int>(b);
3) приведение вида var myInterface = (IInterface)myClass или var myInterface = myClass as IInterface

var точно не используется в случае "да все знают что Foo() вернет float" или для вызовов функций типа MyFuncThatReturnsInt()

Ну и анонимные типы как другой случай.
Re: Тернарный оператор '? :'
От: Sharov Россия  
Дата: 30.11.15 09:53
Оценка:
Здравствуйте, _ichensky, Вы писали:


>
>2.  
>return func(a == 0 ? a : a + 100500);
>


Этот вариант вполне читабельный. Решарпер (у меня 7.0) в соотв. случаях именно так код и преобразует. Меня это вполне устраивает.
Кодом людям нужно помогать!
Re[5]: А зачем тут var
От: Sinix  
Дата: 30.11.15 10:49
Оценка: +1
Здравствуйте, Doc, Вы писали:

Doc>Основные случае, когда тип точно известен и указан явно, не так и сложно перечислить

Doc>1) new SomeClass()
Doc>2) generic методы c явным указанием типа, когда он же и является типом результата: var x = Foo<int>(b);
Doc>3) приведение вида var myInterface = (IInterface)myClass или var myInterface = myClass as IInterface

Ещё забыл сценарий 4, когда программист хочет, чтобы тип выводился автоматом, как с генериками, лямбдами, ветвями в conditional operator и тд и тп.

Это очень удобно для кода в SRP-стиле. Хотя там вообще нет никакой разницы что использовать.
Методы небольшие => область действия переменной не вылазит за экран текста => легко отследить что откуда пришло.

В простынях на сотни строк, разумеется, типы лучше указывать явно, чтобы не сносило крышу при попытке разобраться.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.