2015-05-29 4 views
1

Так что я скрывался здесь последние несколько лет и, наконец, пришел к ситуации, когда я НЕ нашел здесь существующего ответа. Сам вопрос довольно прост.Условный тернар с вызовом метода на db


Предположит следующее заявление (нет конкретного языка синтаксиса):

var result = fetchFromDb() == null ? defaultValue : fetchFromDb().property; 

То, что я хочу знать: это компилятор в Java или C# есть способ оптимизировать это утверждение или будет действительно быть двумя вызовами метода fetchFromDb(), означающим два вызова доступа к БД, два плана выполнения и так далее?

Я уже тестировал это на Java и выяснил, что метод вызывается дважды, но я понятия не имею о возможном кэшировании в фоновом режиме или что-то в этом роде.

Итак: используется тернарный условный метод с плохой практикой? Есть ли способ кэшировать значение по сравнению с встроенным, чтобы сохранить красоту этого стиля?

+1

var result = fetchFromDbSupplyingDefaultValue (defaultValue); –

+1

Он не будет оптимизирован, если это не известная функция. –

+1

Люди часто думают, что тройной оператор заменяет 'if', а это не так. Хотя стиль может быть привлекательным во многих случаях, просто не имеет смысла пытаться заставить все ifs тройным операторам (это с точки зрения Java/C#). – Kayaman

ответ

2

Да, это всегда будет два вызова. Дело в том, что между первым вызовом и вторым вызовом результат fetchFromDb() может измениться. Компилятор не может предсказать это изменение стоимости, если оно не является известным детерминированным function. Определяющим является ключевое слово здесь. Даже тогда не может быть оптимизации компилятора для таких вещей.

Использование тернарного состояния с помощью методов - это не плохая практика сама по себе, но она менее читаема, чем простая инструкция if.

Единственный способ гарантировать единый вызов - это код для одного вызова.

var result; 
var fetchResult = fetchFromDb(); 
if (fetchResult == null) { 
    result = defaultValue; 
} else { 
    result = result.property; 
} 

Или, если вы настаиваете на использовании троичной

var fetchResult = fetchFromDb() 
var result = (fetchResult == null) ? defaultValue : result.property; 

Я действительно думаю, что это гораздо яснее, чем тройным. Наличие кода на одной строке не выводит красивый код.

+0

Благодарим вас за это. Тем не менее, было бы неплохо иметь переменную 'value', доступную в тернарном состоянии, точно так же, как у вас есть настраиваемый набор свойств в C# ... конечно, db может измениться между двумя вызовами, но зачем мне это нужно? это изменение? Сделало бы сравнение бессмысленным вообще. –

0

На самом деле

var result = fetchFromDb() == null ? defaultValue : fetchFromDb().property; 

Сделает два вызова в else случае. Чтобы избежать двойного звонка:

var result; 
var fetch = fetchFromDb(); 
if (fech == null) { 
    result = defaultValue; 
} else { 
    result = fetch.property; 
}