104

In c#, is there any difference in the excecution speed for the order in which you state the condition?

if (null != variable) ...
if (variable != null) ...

Since recently, I saw the first one quite often, and it caught my attention since I was used to the second one.

If there is no difference, what is the advantage of the first one?

mr_georg
  • 3,635
  • 5
  • 35
  • 52
  • 3
    http://www.wikiwand.com/en/Yoda_conditions – Ivan Chau Dec 27 '15 at 05:32
  • Some programming languages support to initialize value in if condition. In such languages if we want to compare LValue with RValue it's good practice to use literal to left side like if(1==i). so accidentally if we put = rather == then it gives compiler error. – Jugal Panchal Mar 24 '17 at 15:18

9 Answers9

170

It's a hold-over from C. In C, if you either use a bad compiler or don't have warnings turned up high enough, this will compile with no warning whatsoever (and is indeed legal code):

// Probably wrong
if (x = 5)

when you actually probably meant

if (x == 5)

You can work around this in C by doing:

if (5 == x)

A typo here will result in invalid code.

Now, in C# this is all piffle. Unless you're comparing two Boolean values (which is rare, IME) you can write the more readable code, as an "if" statement requires a Boolean expression to start with, and the type of "x=5" is Int32, not Boolean.

I suggest that if you see this in your colleagues' code, you educate them in the ways of modern languages, and suggest they write the more natural form in future.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 7
    My colleagues all drive me nuts with this, and wanting curly-brackets even for a single statement after the if... (in case you add something later 'without realising'). Roll on F# and Boo (and YAML), if your language is unreadable without indentation, make it part of the language, I say. – Benjol Nov 22 '08 at 22:09
  • 51
    Adding braces *is* reasonable, IMO - C# certainly doesn't make any attempt to stop it from being a problem. That's very different to the "constant == variable" issue. – Jon Skeet Nov 23 '08 at 08:06
  • 6
    a if( this!=that ){ performAsSuch(); } is quite healthy actually. The argument of "later addition" seams to me about as fragile as not avoiding/spoting if (a=5) typos – jpinto3912 May 29 '09 at 21:56
  • 3
    @jpinto: I'm not really sure what you're trying to say here - that you *do* like braces around single statements, or that you don't? The difference between this and the variable business in the question is that in C# the code with a typo is *invalid* code so the compiler will stop it. The same *isn't* true for not putting braces in. – Jon Skeet May 29 '09 at 22:10
  • 4
    @Benjol Don't forget to always supply an empty `else { }` clause in case someone needs to add something there later and forgets to write the `else` keyword themselves. (Joke) – Jeppe Stig Nielsen May 03 '13 at 21:42
13

Like everybody already noted it comes more or less from the C language where you could get false code if you accidentally forget the second equals sign. But there is another reason that also matches C#: Readability.

Just take this simple example:

if(someVariableThatShouldBeChecked != null
   && anotherOne != null
   && justAnotherCheckThatIsNeededForTestingNullity != null
   && allTheseChecksAreReallyBoring != null
   && thereSeemsToBeADesignFlawIfSoManyChecksAreNeeded != null)
{
    // ToDo: Everything is checked, do something...
}

If you would simply swap all the null words to the beginning you can much easier spot all the checks:

if(null != someVariableThatShouldBeChecked
   && null != anotherOne
   && null != justAnotherCheckThatIsNeededForTestingNullity
   && null != allTheseChecksAreReallyBoring
   && null != thereSeemsToBeADesignFlawIfSoManyChecksAreNeeded)
{
    // ToDo: Everything is checked, do something...
}

So this example is maybe a bad example (refer to coding guidelines) but just think about you quick scroll over a complete code file. By simply seeing the pattern

if(null ...

you immediately know what's coming next.

If it would be the other way around, you always have to scan to the end of the line to see the nullity check, just letting you stumble for a second to find out what kind of check is made there. So maybe syntax highlighting may help you, but you are always slower when those keywords are at the end of the line instead of the front.

Oliver
  • 43,366
  • 8
  • 94
  • 151
11

There is a good reason to use null first: if(null == myDuck)

If your class Duck overrides the == operator, then if(myDuck == null) can go into an infinite loop.

Using null first uses a default equality comparator and actually does what you were intending.

(I hear you get used to reading code written that way eventually - I just haven't experienced that transformation yet).

Here is an example:

public class myDuck
{
    public int quacks;
    static override bool operator ==(myDuck a, myDuck b)
    {
        // these will overflow the stack - because the a==null reenters this function from the top again
        if (a == null && b == null)
            return true;
        if (a == null || b == null)
            return false;

        // these wont loop
        if (null == a && null == b)
            return true;
        if (null == a || null == b)
            return false;
        return a.quacks == b.quacks; // this goes to the integer comparison
    }
}
DanW
  • 1,976
  • 18
  • 14
  • 13
    This is wrong. Downvoted. Simply point the mouse over the `==` operator and rest it there, and you will see that the user-defined overload is used in both cases. Of course it can make a subtle difference if you check `a` before `b` and then swap the position of `a` from right operand to left operand. But you could also check `b` before `a`, and then `b == null` would be the one which reversed order. This is all confusing to have the operator call itself. Instead, cast either operand (or both) to `object` to get the desired overload. Like `if ((object)a == null)` or `if (a == (object)null)`. – Jeppe Stig Nielsen May 03 '13 at 21:38
  • Late Party; if that did even work; It's a nasty code smell as you're making a class require its == be overloaded, but arbitrarily! – Russ Clarke Jun 22 '22 at 12:43
10

I guess this is a C programmer that has switched languages.

In C, you can write the following:

int i = 0;
if (i = 1)
{
    ...
}

Notice the use of a single equal sign there, which means the code will assign 1 to the variable i, then return 1 (an assignment is an expression), and use 1 in the if-statement, which will be handled as true. In other words, the above is a bug.

In C# however, this is not possible. There is indeed no difference between the two.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
  • 1
    "In C# however, this is not possible" without the compiler complaining, as the if statement requires a boolean expression, and the one provided is of type int. – Robert Harvey Sep 17 '09 at 15:08
5

In earlier times, people would forget the '!' (or the extra '=' for equality, which is more difficult to spot) and do an assignment instead of a comparison. putting the null in front eliminates the possibility for the bug, since null is not an l-value (I.E. it can't be assigned to).

Most modern compilers give a warning when you do an assignment in a conditional nowadays, and C# actually gives an error. Most people just stick with the var == null scheme since it's easier to read for some people.

Rik
  • 28,507
  • 14
  • 48
  • 67
  • All C# compilers (note this is a C# question) should fail to compile an "if" statement where the expression isn't a Boolean though... – Jon Skeet Nov 07 '08 at 09:04
4

I don't see any advantage in following this convention. In C, where boolean types don't exist, it's useful to write

if( 5 == variable)

rather than

if (variable == 5)

because if you forget one of the eaqual sign, you end up with

if (variable = 5)

which assigns 5 to variable and always evaluate to true. But in Java, a boolean is a boolean. And with !=, there is no reason at all.

One good advice, though, is to write

if (CONSTANT.equals(myString))

rather than

if (myString.equals(CONSTANT))

because it helps avoiding NullPointerExceptions.

My advice would be to ask for a justification of the rule. If there's none, why follow it? It doesn't help readability

0

To me it's always been which style you prefer

@Shy - Then again if you confuse the operators then you should want to get a compilation error or you will be running code with a bug - a bug that come back and bite you later down the road since it produced unexpected behaviour

TheCodeJunkie
  • 9,378
  • 7
  • 43
  • 54
  • I don't think I've ever heard of anyone preferring the "constant == variable" form *other* than for reasons of safety, which are already dealt with in C#. – Jon Skeet Nov 07 '08 at 09:06
  • I prefer "variable == constant" myself, but I've seen programmers adopt the reversed because they feel it reads more natural to them. – TheCodeJunkie Nov 07 '08 at 09:10
  • 1
    Were they all people with years of C brainwashing behind them, or was it a genuine choice? – Jon Skeet Nov 07 '08 at 09:29
0

As many pointed out, it is mostly in old C code it was used to identify compilation error, as compiler accepted it as legal

New programming language like java, go are smart enough to capture such compilation errors

One should not use "null != variable" like conditions in code as it very unreadable

Anand Shah
  • 11
  • 1
-4

One more thing... If you are comparing a variable to a constant (integer or string for ex.), putting the constant on the left is good practice because you'll never run into NullPointerExceptions :

int i;
if(i==1){        // Exception raised: i is not initialized. (C/C++)
  doThis();
}

whereas

int i;
if(1==i){        // OK, but the condition is not met.
  doThis();
}

Now, since by default C# instanciates all variables, you shouldn't have that problem in that language.

Gad
  • 41,526
  • 13
  • 54
  • 78
  • 1
    I am not sure what compiler you are using for the first bit of code, but it should compile (generally with a warning). The value of i is undefined, but it does have SOME value. – Dolphin Jun 09 '09 at 15:43
  • Of course both codes will compile! That's exactly the problem. Try running the first code and you'll understand what I meant by "Exception raised"... – Gad Jun 09 '09 at 16:17
  • is also don't get the difference between the two. Can you ellaborate? – mfazekas May 14 '10 at 16:02
  • No exception unless you declare int *i in C/C++, and even in that case it will compare pointers and not throw any exception ... Like Dolphin stated the value is undefined but it will not generate any Exceptions. – Cobusve May 27 '10 at 15:26
  • no exceptions, let's say `i` is a random value without a proper initialization. the expression has completely the same semantic in c/c++ – Raffaello Dec 10 '17 at 18:43