views:

826

answers:

17

They both do the same thing. Is one way better? Obviously if I write the code I'll know what I did, but how about someone else reading it?

if (!String.IsNullOrEmpty(returnUrl))
{
    return Redirect(returnUrl);
}
return RedirectToAction("Open", "ServiceCall");

OR

if (!String.IsNullOrEmpty(returnUrl))
{
   return Redirect(returnUrl);
}
else
{
    return RedirectToAction("Open", "ServiceCall");
}
+9  A: 

the second way is better, no confusion about what you mean...

Scott Evernden
+1 An explicit else is always better for readability by the unfamiliar
cdeszaq
Well, I'd still disagree. Forced to choose between the two I'd pick the first.
Andrew Rollings
I'm with Andrew. I prefer the guard clause at the top. The 'return' does the work of the 'else'.
Matt Hamilton
yes of course logically they do the same thing. but the question asked about someone else picking up this code and figuring out what was meant. Its simply a fact: for a random reader, you have a higher chance of confusion using the first version vs the second
Scott Evernden
It's certainly not a fact. I find the first slightly easier to understand.
recursive
+29  A: 
return String.IsNullOrEmpty(returnUrl) ? 
   RedirectToAction("Open", "ServiceCall") : 
   Redirect(returnUrl);

I prefer that.

Or the alternative:

return String.IsNullOrEmpty(returnUrl)  
   ? RedirectToAction("Open", "ServiceCall")  
   : Redirect(returnUrl);
Andrew Rollings
This is less readable than either of the options listed in the question.
Bruce Alderman
Only if you're not intimately familiar with the ternary ?: operator.I personally find it clearer.
Andrew Rollings
I like it better too (deleted my exactly that same answer)
Ray
IMO, familiarity with the language should be a given, not familiarity with the code. Any common constructs should be obvious to a reader.
Andrew Rollings
It's not so much the ternary operator. All the parentheses and the very long line make your code less readable. But it comes down to a matter of taste.
Dana
I also prefer this style in place of simple if/else constructs.
One set of parentheses can be remove (first set) and line breaks after ? and : make it much more readable.
Ray
Oh, and I agree on the line breaks :)
Andrew Rollings
I find it clearer when ? and : are at the beginning of each branch.
Ates Goral
The line breaks greatly improve readability.
Bruce Alderman
@Ates Goral: Added as an alternative. I tend to agree with you.
Andrew Rollings
I like it much better with the linebreaks :)
Dana
Matter of opinion, of course, but I prefer to use the ternary operator only for simple assignments. Not so much for controlling major flow in the program.
David Grant
Agreed. I think it's also okay for simple return statements like this too.
Andrew Rollings
I think it's better this way because you're writing less and using a positive assertion at the beginning
JayTee
Ternary operator is not acceptable if it spans more than 1 line. You might as well write Perl.
Tim Williscroft
Splitting it across lines clarifies it. One term per line: Condition, true action, false action. It's not rocket surgery :)
Andrew Rollings
+1 on splitting so that lines start with operator characters.-1 for using ternary operator at all. If this code is surounded by other code it is very hard to notice there is any sort of return happening at all.
Tom A
Clarification: Sure, it is very clear that a return is happening (since that is the leading key word), but it feels awkward to bury alternative flow logic in a statement type that is generally used to proved alternative values.
Tom A
@Tom A: Horses for courses I guess :) I read it as providing alternative values for the return statement.
Andrew Rollings
@Tom A: Also, I'd expect this to be the last line in a method.
Andrew Rollings
@Andrew: Good point -- if it is the last statement then it is clear, and pretty clean. All in all, it's one of those things that is cool when *you* do it, but annoying when anyone else does. ;)
Tom A
@Tom A: hehehe. too true!
Andrew Rollings
+9  A: 

I think this is a fairly small matter of style. I'd argue that your two samples are equally readable.

I prefer the former, but other people prefer only one exit point from a function and would probably suggest something like:

if (!String.IsNullOrEmpty(returnUrl))
{
   result = Redirect(returnUrl);
}
else
{
    result = RedirectToAction("Open", "ServiceCall");
}

return result;
Dana
I was half through writing that exact code sample. The single exit point can make for a nasty nested mess of conditionals sometimes.
Adam Hawes
I'd argue that single exit point makes for a nasty mess nearly all the time. I think it's a holdover from trying to tame the use of goto.
rmeador
Oh, I agree with you guys. I meant to point out another common way of writing this kind of thing.
Dana
+4  A: 

I like the first example because it's more obvious that this excerpt will return. If both returns are in indented blocks, it takes just a little more mental effort to tell.

recursive
This was exactly my thoughts.
Jeffrey L Whitledge
That's actually a pretty nice defense for the first example. I intuitively prefer that, but I never really found a way to explain my preference to others. Thanks! +1
Erik van Brakel
+1 Yes, I always think there is something missing after the closing else }.
kenny
+22  A: 

I believe it's better to remove the not (negation) and get the positive assertion first:

if (String.IsNullOrEmpty(returnUrl))
{
   return RedirectToAction("Open", "ServiceCall");
}
else
{
    return Redirect(returnUrl);
}

-or-

// Andrew Rollings solution
return String.IsNullOrEmpty(returnUrl) ? 
                    RedirectToAction("Open", "ServiceCall") : 
                    Redirect(returnUrl);
Gavin Miller
Why is that the *right* way? I much prefer the common case at the top.
Ray
+1 I think the negation is a bigger issue concerning 'cleanliness' then the braces.
Daan
Positive assertion should be at the top.
Gavin Miller
I don't know - I prefer the other way:if (expected case) ... else ...even if it does add an extra ! operator.
mbeckish
I believe (and don't quote me on this) but the common case at the top is legacy from the days were processors couldn't optimize the best path (IE poor pipelining) - IMHO it's just not relevant anymore.
Gavin Miller
Why should the positive assertion be at the top? Obviously it's a matter of taste, not a fact as you're trying to pass it off as.
Ray
I have to say, I prefer my solution (which is updated from that which you've copied above... Now with added formatting goodness).
Andrew Rollings
Ahh - I'll update that then
Gavin Miller
Actually, why copy it at all? It's right there in my answer.. (Not being funny, just puzzled).
Andrew Rollings
Personally, I think both have their place in this world, thus using both. ;)
Gavin Miller
I also had added it before all the edits were done to yours... specifically removing the negation
Gavin Miller
Alright :) But if your answer gets accepted because of it, I'm kicking your ass! ;)
Andrew Rollings
lol - fair enough
Gavin Miller
Positive assertions are generally easy to read than negations, which is why they are preferred. If you have a one line 'is null' type of test, then sure, put that first. But, the general rule is aim for positive comparisons.
Travis
A: 

How about:

if (!String.IsNullOrEmpty(returnUrl))
    return Redirect(returnUrl);
else
    return RedirectToAction("Open", "ServiceCall");
mbeckish
I would recommend you to use the brackets ALWAYS...
OscarRyz
Hmmmm. For the sake of sustainability, this is something I'd stay away from. It's a good rule, typically, to always enclose these types of statements in braces. Just Google C/C++ coding standards and you'll find this to be a common theme.
Ditto. Always put braces.
Owen
Agreed about using braces. If you ever have to add a line before the return, you'll appreciate having them.
Bruce Alderman
+19  A: 

One style issue:

if (String.IsNullOrEmpty(returnUrl))
{
    return RedirectToAction("Open", "ServiceCall");
}
return Redirect(returnUrl);

When you cancel out the double negation it reads a whole lot better, no matter which brace style you choose. Code that reads better is always best ;)

krosenvold
This also has the advantage (at least in this example) of making the common case the default return.
Bruce Alderman
I like this one the best, out of all of the variations. It's clean, consistent, obvious and easily readable.
Paul W Homer
Agreed. I didn't notice the ! since I thought it was more about the bracing.
kenny
There's no surprises, which I think is important...
krosenvold
This also follows the pattern to return as soon as possible to keep the program flow clear.
VVS
A: 

Don't think there's a better way... it depend on each developer. That's why before starting a project you should decide what is the coding standard ...

Brainthegrinch
+1  A: 

Eliminate the 'double-negative' and use the fully-expanded style. I am sure most compilers now can suitably optimize the code on your behalf, so no reason to take short-cuts for readability.

A: 

I like the first better.

if ( ) 
{
    return ... 
}
return

For me it reads like a "default" you can chain more conditions but at the end there is a default.

Of course it is a matter of style.

Additional question.

Is it C# style to put the square brackets and in a single line?

if ( ) 
{
}
else
{
}

I have seen this permeated into Java code samples in SO, and I'm wondering this is the root cause.

EDIT

@Owen. I mean, Is it C# style using this form?

if ()  
{
    code ... 
}
else
{
    code...
}

Rather than this ( which would be Java preffered )

if ( ) { 
    code ... 
} else { 
   code ...
}

I have had some arguments in the past about this, but most of the times, only with people that come from C# background.

OscarRyz
Not necessarily C# style, just good style regardless of the (C-esque) language. See the comments to mbeckish's reply.
Owen
A: 

The first one. You don't need any else if you are returning a value inside the if statement. So:

if (!String.IsNullOrEmpty(returnUrl))
    return Redirect(returnUrl);
return RedirectToAction("Open", "ServiceCall");
igorgue
ewww... wash your mouth out with soap!
Andrew Rollings
interesting... did you deleted the offending comments? or you're just saying it because of the code I suggest, that btw is how the Linux kernel creator suggest it has to be :)
igorgue
+1  A: 

If it's the entirety of the method then I'd say the second (using the else) is a bit more elegant. If you have preceding code or (especially) much more code before the return in the else case, I'd say it's better not to put the else. Keeps from code becoming too indented.

i.e. either:

void myfunc()
{
    if (!String.IsNullOrEmpty(returnUrl))
    {
        return Redirect(returnUrl);
    }
    else
    {
        return RedirectToAction("Open", "ServiceCall");
    }
}

or

void myfunc()
{
    // ... maybe some code here ...

    if(!String.IsNullOrEmpty(returnUrl))
    {
       return Redirect(returnUrl);
    }

    // ... a bunch of other code ...

    return RedirectToAction("Open", "ServiceCall");
}
Owen
A: 

As here, but more readable:

return
  string.isNullorEmpty(returnUrl) ? 
     RedirectToAction("Open", "ServiceCall") :
     Redirect(returnUrl);

This way works, is readable and non-redundant.

Skeolan
A: 

From a maintenance perspective I prefer the first version. I've seen less errors with a consistent "get out early" style.

The ternary operator (?:) is OK, but only if it is very unlikely that new code will be inserted before the 2nd return statement. Otherwise when the time comes to add something new into the 2nd code path, the ternary statement has to go back to being an if/else block anyway.

devstuff
A: 

When I have only one line sometimes I compact the if statement like this:

if(String.IsNullOrEmpty(returnUrl)) { 
  return RedirectToAction("Open", "ServiceCall"); 
}
else{ return Redirect(returnUrl); }

Although when I look at it, Andrew Rollings might have the best solution although I had never thought of using it until today.

Ray Hidayat
A: 

LFSR's "else" solution is the most maintainable and readable.

Using a separate else clause allows logic to be added without inadvertently changing the flow. And it's bad enough having multiple exit points without hiding two of them in a single ternary operator statement!

Tom A
A: 

This code feels messy because of the unavoidable double-negative logic (and shuffling things around isn't going to clear it up). Whichever arrangement you use, I think you should add some comments so that the reader doesn't need to do a double-take:

if (!String.IsNullOrEmpty(returnUrl))
{
  // hooray, we have a URL
  return Redirect(returnUrl);
}
else
{
  // no url, go to the default place
  return RedirectToAction("Open", "ServiceCall");
}
too much php