tags:

views:

348

answers:

6

What the title says! I see it from times to times and I'd like to know why. Is there any difference at all?

+19  A: 

It's an old habit to avoid the accidental typo of myVar = null. (whoops). It's still helpful in some languages, but c# will protect you from doing it, so it's not necessary there.

Rex M
Just that?
devoured elysium
@devoured yep - just that.
Rex M
Also, it's a general habit of saying "someConst == myVar", where someConst happens to be null in this case. Some scripting languages may translate the above as "someConst.equals(myVar)", and if you do it the other way around, you may get an NPE.
Bugmaster
Correction: C# won't let you do it.
Noldorin
@Noldorin how do you do an assignment in a conditional in VB.NET?
Rex M
@Rex - I believe Noldorin is simply drawing a distinction between the language and the library (which is a good distinction to make). Also, C# _does_ allow assignment in a conditional as long as the assignment is a boolean value to a boolean variable (this does generate a warning though).
Andrew Hare
@Andrew that's fair. It's pretty common to see .NET as shorthand for c#+VB.NET, but I guess that could cause some confusion, so I'll change it.
Rex M
null == myVar is also much less readable than myVar == null.
Konstantin Spirin
+8  A: 

It's a holdover from C where older compilers would not catch this:

if (foo = null)

when you mean this:

if (foo == null)

The classic joke example is this mistake:

if (fireTheNukes = true)
    fireTheNukes();

This is generally accepted as an archaic pattern as any compiler worth its salt will catch an assignment within a conditional statement. I would avoid this pattern in your code as it serves no purpose these days.

Andrew Hare
@Andrew: I thought if(foo = null) was a perfectly valid statement (assign the value to foo and then check if it's true). I didn't think it had anything to do with compilers not "catching" it.
Esteban Araya
@Esteban - what language and compiler? While the C# compiler _will_ allow a boolean assignment in a conditional statement it will also generate a "did you really mean to do this?" warning.
Andrew Hare
+2  A: 

It's an old defensive habit. If you put the constant on the left, then forgetting the second equals sign results in a compile error. In the more normal format, forgetting the second equals sign results in assigning null to your variable.

In other words,

myVar = null

is harmful and surprising, whereas

null = myVar

gets caught by the compiler.

mtnygard
+2  A: 

It's a habit of C programmers, one that has been brought to C# in this case, but is in fact totally unnecessary.

Consider in C that if you accidentally type if (myVar = null), the compiler will do the assignment and not complain. Switching around the order of myVar and null insures that a compiler error is generated if == is inadvertantly mistyped as =. C#, however, generates a compiler warning in either case, so this quirk is unneccessary.

Noldorin
+2  A: 

It comes from C/C++ to catch leaving out one equal sign:

myVar = null

But it is not needed in C#.

Peter Mortensen
+1  A: 

As others have mentioned, it's a defensive tactic against problems that may arise from the fact that in C and some C derivatives (including C#) an assignment expression evaluates to the value of that assignment. This is what allows you to do:

if (a = true) { /* This will always get done, as "a = true" evals to true */ }

and

int a = b = c = d = 10;

As assignment is right associative this is effectively

int a = (b = (c = (d = 10)));

where each expression inside a brace pair will evaluate to the value of the assignment, which is in this case 10 and a, b, c and d will thus all be 10.

To avoid potential mistakes -- mixing up the assignment and equality operators -- some programmers prefer to always put the constant on the left, as if the assignment operator is accidentally used the compiler will complain that you cannot assign to a constant.

This is, however, less of an issue in C# for two reasons. Firstly, unlike C, C# does not allow arbitrary values to be interpreted as a boolean value.

This was necessary in C as it had no true boolean type, it just relied on the interpretation of other values like integers (where 0 is false and non-zero is true) or pointers (where NULL is false). This meant you could then do something like

if (10) { /* This will always get done */ }
if (0) { /* This will never get done */ }
if (p) { /* This will get done is p is not null */ }
if (NULL) { /* This will never get done */ }

However, because C# does not allow arbitrary expressions to be interpreted as a boolean these will not work in C#. It also means that

if (a = 10) { }

will not compile in C#, as the expression "a = 10" evaluates to the value of the expression, 10, which cannot then be interpreted as the required boolean value.

The second reason it is less of an issue is that in the, now much smaller, percentage of cases where the result of the assignment can be interpreted as a boolean value the compiler issues a warning to make sure you really did mean to do that.

The warning can be suppressed with

#pragma warning disable 665

However, the presence of such code is often a bad code smell and is probably best dealt with by refactoring to make the code clearer.

ICR