2016-12-05 12 views
0

У меня есть этот код, где LongMethodWithResult это метод, который занимает много времени для запуска:Сжатый способ использования условного оператора

object o = LongMethodWithResult() == someVal ? LongMethodWithResult() : someOtherResult; 

Теперь метод LongMethodWithResult оценивается в два раза, не так ли?

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

public static object ConciseConditionalOperator(object a, object b, object c) 
{ 
    return a == b ? a : c; 
} 

Но я был бы заинтересован в том, есть ли лучший способ сделать это или некоторые функции, обслуживаемые C# или .NET.

Любые идеи приветствуются!

+4

В вашем случае вы не можете сделать 'объекта о = LongMethodWithResult() == someVal? someVal: someOtherResult; '? – KMoussa

+0

Я бы, как правило, ограничил использование условных выражений простым логическим выражением без побочных эффектов, которые вызывают выбор между двумя значениями. Типичным примером K & R является выбор между множественным числом s и пустой строкой при печати текста в зависимости от числа! = 1. –

+0

Чтобы избежать яркого ярлыка @ PeterB (все еще проницательного), вы можете запросить отношение, отличное от идентификатора, например. 'LongMethodWithResult() <= someVal? ... ' –

ответ

0

Как правило, вы правы. В вашем примере LongMethodWithResult выполняется дважды. Чтобы избежать этого, вам нужно сначала сохранить результат LongMethodWithResult:

var result = LongMethodWithResult(); 
object o = result == someVal ? result : someOtherResult; 

Как сказал Питер B в своем ответе, пример вы предоставили это особый случай, когда вам не нужно, что, как, когда LongMethodWithResult()-х результат равен значению, которое вы уже знаете, нет необходимости называть его снова. Вы можете просто вернуть значение, которое вы уже знаете.

Однако часто необходимо следующее:

var result = LongMethodWithResult(); 
object o = result == null ? defaultResult : result; 

Вы можете, однако, заменить последнюю конструкцию с простым:

object o = LongMethodWithResult() ?? defaultResult; 
+1

... и для последнего C# предлагает элегантный 'объект o = LongMethodWithResult() ?? defaultresult; '. –

+0

@ PeterA.Schneider Да, я собирался написать это, но позвоню от клиента. –

+0

Кровавые отвлечения от важного материала ;-). –

4

В данном конкретном случае вы могли бы использовать это:

object o = LongMethodWithResult() == someVal ? someVal : someOtherResult; 


Если вы предпочитаете другую запись, или если вы хотите, чтобы избежать указания someVal дважды, то вы можете создать метод расширения (в статике класс):

public static T IfEqualThenElse<T>(this T valueToCheck, T value1, T value2) 
    where T : System.IEquatable<T> 
{ 
    return valueToCheck.Equals(value1) ? value1 : value2; 
} 

Использование:

var o = LongMethodWithResult().IfEqualThenElse(someVal, someOtherResult); 
+0

спасибо за ваш ответ! – florien