0

I have this code, where LongMethodWithResult is a method that takes a long time to run:

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

Now the LongMethodWithResult method is evaluated two times, isn't it?

I know I could write a method that uses variables to store the result of the long method, something like this:

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

But I would be interested in whether there is a best way of doing this, or some functionality served by C# or the .NET.

Any ideas are welcomed!

4
  • 4
    In your case can't you do object o = LongMethodWithResult() == someVal ? someVal : someOtherResult; ? Commented Dec 5, 2016 at 10:00
  • I would as a rule of thumb limit the use of conditional expressions to simple logical expressions without side-effects which trigger a choice between two values. K&R's typical example is choosing between a a plural s and an empty string when they print a text, depending on a number being != 1. Commented Dec 5, 2016 at 10:07
  • To avoid @PeterB's (still insightful) shortcut you could ask for a relation other than identity, e.g. LongMethodWithResult() <= someVal ? ... Commented Dec 5, 2016 at 10:11
  • @KMoussa and @Peter A. Schneider you are true, ok, let's say the condition is LongMethodWithResult() <= someVal Commented Dec 5, 2016 at 10:22

2 Answers 2

5

In this specific case you could use this:

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


If you prefer a different notation, or if you want to avoid specifying someVal twice, then you could create an Extension method (in a static class):

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

Usage:

var o = LongMethodWithResult().IfEqualThenElse(someVal, someOtherResult);
Sign up to request clarification or add additional context in comments.

Comments

1

Generally you are right. In your example, the LongMethodWithResult is executed twice. To avoid that, you need to first store the result of LongMethodWithResult:

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

As Peter B said in your answer, the example you provided is a special case where you don't need that, as when LongMethodWithResult()'s result equals a value you already know, there's no need to call it again. You can just return the value you already know.

However, oftentimes the following is necessary:

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

You can, however, replace the last construct with a simple:

object o = LongMethodWithResult() ?? defaultResult;

9 Comments

... and for the latter C# offers the elegant object o = LongMethodWithResult() ?? defaultresult;.
@PeterA.Schneider Yes I was going to write that but go a call from a customer.
Bloody distractions from the important stuff ;-).
Yeah, I cut him off, too. Couldn't concentrate on him anyway. :-D
Thanks for the conclusion! Further considering, do you thing it'd be useful if C# allowed a syntax something like (a, b)?: c, where a and b could be the result of two long-running methods, and the expression would be the same as a == b ? a /*or b*/ : c?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.