.Net Framework >> Is it (null == something) or (somethin g == null)?

by Jon Skeet [C# MVP] » Mon, 19 Jul 2004 17:26:21 GMT

Stano < XXXX@XXXXX.COM > wrote:
> I frequently see .NET coders, especially C# coders, use the following syntax:
>
> if (null == something){DoSomething();}
>
> instead of the much more intuitive
>
> if (something == null) {DoSomething();}
>
> Is this an example of anally-retentive programming held over from
> some bygone C era, or are there actual benefits to using this syntax
> in the .NET world?

The former, I believe.

> I would have thought a modern compiler would not care about syntax
> order, as it would optimize such a statement to produce the best
> execution speeds. Can anyone enlighten me?

Everyone I've asked about it has basically said it's a habit from C/C++
days, where they wanted to avoid the typo of

if (something = null)

Some didn't know that in C# that's not legal code, and others just
preferred to stick to their existing habits.

--
Jon Skeet - < XXXX@XXXXX.COM >
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

.Net Framework >> Is it (null == something) or (somethin g == null)?

by Jon Skeet [C# MVP] » Sat, 24 Jul 2004 05:53:45 GMT



If I change language, I precisely *don't* want my code to look as if
it's in the previous language - otherwise I'm likely to adopt the same
idioms and "think" in the previous language, which is a very bad idea.
Some of the worst Java I've seen was written by people who were trying
to make it C++, and I'm sure the same would be true if I tried to write
C as if it were C#.


Whereas IME, it suggests that the programmer *hasn't* given a thought
as to whether an idiom which is usually regarded as sacrificing some
readability for typo-safety is still necessary in the new language.

--
Jon Skeet - < XXXX@XXXXX.COM >
http://www.pobox.com/ ~skeet
If replying to the group, please do not mail me too

.Net Framework >> Is it (null == something) or (somethin g == null)?

by Jon Skeet [C# MVP] » Sat, 24 Jul 2004 07:40:30 GMT


I admit that no *semantic* harm is done.


No, I believe it *does* hurt readability. I believe it's an unintuitive
way of writing the code (as did the OP, btw) which people only ever did
in C/C++ to avoid typos. Tell me, do you think anyone would have done
it if there *hadn't* been the potential for syntactically correct but
semantically disastrous errors in C/C++? I don't.

Writing code in the most natural way is a good thing. This *isn't*
writing code in the most natural way - it's writing code in a way which
was developed to avoid a problem in a different language.

--
Jon Skeet - < XXXX@XXXXX.COM >
http://www.pobox.com/ ~skeet
If replying to the group, please do not mail me too

.Net Framework >> Is it (null == something) or (somethin g == null)?

by Jon Skeet [C# MVP] » Sat, 24 Jul 2004 10:39:27 GMT


But only because the idiom is common there to avoid typos - not because
it's a fundamentally readable style.


I think the clincher is to ask yourself how you'd read the meaning of
the line of code out loud to a colleague in an informal way. Suppose
you were tracing some code to work out what should happen, how would
you read out:

if (5==x)
{
DoSomething();
}
else
{
DoSomethingElse();
}

I'd read that out as "If x is 5, we call DoSomething, otherwise we call
DoSomethingElse". The idea of reading it as "If 5 is x, we call
DoSomething, otherwise we call DoSomethingElse" is very strange to me -
not in code terms, but in *English* terms. I don't know if there are
other natural spoken languages where it would be a natural way of
saying it - and if there are such languages, then native speakers of
those languages have much more reason to use the idiom. Otherwise, I
think it should be avoided in languages where it's not necessary for
safety's sake.

--
Jon Skeet - < XXXX@XXXXX.COM >
http://www.pobox.com/ ~skeet
If replying to the group, please do not mail me too

.Net Framework >> Is it (null == something) or (somethin g == null)?

by Jon Skeet [C# MVP] » Tue, 27 Jul 2004 01:30:24 GMT


So write it as the (more natural, IMO)

if (a)
{
Console.WriteLine("allo");
}


Yup. And I can't remember the last time I wrote a conditional comparing
the value of a variable with a boolean constant in that way.


Except the compiler catches is for every type other than boolean
already:

if (something=null)

won't compile in C#. The equivalent would in C/C++, which is where the
practice comes from - but aside from the incredibly rare occasions
where you're comparing the value of a boolean variable with a constant,
it's pointless and reduces readability.

--
Jon Skeet - < XXXX@XXXXX.COM >
http://www.pobox.com/ ~skeet
If replying to the group, please do not mail me too

.Net Framework >> Is it (null == something) or (somethin g == null)?

by Jon Skeet [C# MVP] » Tue, 27 Jul 2004 02:17:15 GMT


It's a reasonable guideline in C/C++, although normally you can
encourage the compiler to warn you if it looks like you've done it
accidentally. In C#, however, it's an abomination.


Exactly.

--
Jon Skeet - < XXXX@XXXXX.COM >
http://www.pobox.com/ ~skeet
If replying to the group, please do not mail me too

.Net Framework >> Is it (null == something) or (somethin g == null)?

by Jon Skeet [C# MVP] » Fri, 30 Jul 2004 05:04:46 GMT


No, they'll both call the overloaded operator. See section 14.2.4 of
the C# language specification for details.

Here's a test program to show that happening:
using System;

class Foo
{
public static bool operator == (Foo y, Foo x)
{
return true;
}

public static bool operator != (Foo y, Foo x)
{
return false;
}

public override int GetHashCode()
{
return 0;
}

public override bool Equals (object o)
{
return true;
}
}

public class Test
{
static void Main()
{
Foo x = new Foo();

if (x==null)
{
Console.WriteLine("Hello");
}

if (null==x)
{
Console.WriteLine("Hello");
}
}
}

--
Jon Skeet - < XXXX@XXXXX.COM >
http://www.pobox.com/ ~skeet
If replying to the group, please do not mail me too

.Net Framework >> Is it (null == something) or (somethin g == null)?

by Jon Skeet [C# MVP] » Sat, 31 Jul 2004 03:33:08 GMT


I think it's usually a good idea - otherwise it comes down to "well, it
doesn't work that way in my test program" which isn't a terribly good
argument, IMO.

--
Jon Skeet - < XXXX@XXXXX.COM >
http://www.pobox.com/ ~skeet
If replying to the group, please do not mail me too

.Net Framework >> Is it (null == something) or (somethin g == null)?

by Jon Skeet [C# MVP] » Wed, 11 Aug 2004 21:20:26 GMT


But it's not just about one person - it's about what works for
whoever's reading the code. I've talked to lots of people who agree
that the if (constant == variable) way of writing things is less
naturally readable than the other way round, but they do it anyway for
safety (in C/C++). That's fine. On the other hand, I have yet to meet
anyone who believes that it's actually *more* readable - the *only*
reason people use that convention is for safety, in my experience. That
means that in a language where the safety isn't required (or rather, is
obtained in other ways) the convention is counter-productive.


I agree that the bracing style argument is relatively stupid - but only
because people can't agree on which is more naturally readable, and
there don't seem to have been objective studies done.

--
Jon Skeet - < XXXX@XXXXX.COM >
http://www.pobox.com/ ~skeet
If replying to the group, please do not mail me too

.Net Framework >> Is it (null == something) or (somethin g == null)?

by Jon Skeet [C# MVP] » Wed, 11 Aug 2004 21:23:57 GMT


If you're going to get picky, you should be talking about the *value*
of x. x itself is variable - its *value* is what we're talking about.
However, when reading code to myself in English, I would ignore the
distinction between the variable and its value, and assume the
equality. That's how English works for me. Even with your expanded
version, however, "x is equal to 5" is much more natural for me than "5
is equal to x". English idiom just doesn't compare constants that way -
you don't say, "If Wednesday is today", you say "If today is
Wednesday".


Not to my eyes, which can much more easily ignore symbols than reorder
things.


They're unnecessary, but they're a bit like the "safety" version of
comparisons in C - they avoid mistakes. They mean that:

1) It's obvious that the line is the "thing to do" if the comparison
matches. Often if you have a multi-line condition, it's not obvious
where the condition ends and the "thing to do" starts, without braces.

2) It makes it hard to make a mistake where you mean something to be in
the same code block, but it doesn't appear in the code block.

There are plenty of code convention documents around suggesting the
uniform use of braces, regardless of whether they're strictly necessary
- it's not just my idea...

--
Jon Skeet - < XXXX@XXXXX.COM >
http://www.pobox.com/ ~skeet
If replying to the group, please do not mail me too

.Net Framework >> Is it (null == something) or (somethin g == null)?

by Jon Skeet [C# MVP] » Fri, 13 Aug 2004 15:10:29 GMT


Ah, but that takes extra effort.


Indeed - and that mental jolt means it's harder to read, IMO. Not
*much* harder to read, but it makes a sufficient difference to make it
worth avoiding where it's unnecessary.


Goodo :)

--
Jon Skeet - < XXXX@XXXXX.COM >
http://www.pobox.com/ ~skeet
If replying to the group, please do not mail me too

Similar Threads

1. Is it (null == something) or (something == null)? - .Net Framework

2. How to check if something is Null

VB.Net 2003, Web Application

Hey there, ive looked around for ages and havnt found a straight
answer. All I want to do is find out if a field in my datatable is Null
For example


If ts.Rows(isel).Item(4) = Null Then

Do something

End if

but have no idea how to do it.. any help would be great

3. ASPX page jscript rt error: null is null or not an object - Asp.Net

4. VB.NET Null to SQL Null (ASP.NET 2.0 GridView)

Hey,

I have everything working now except for this. I have some fields that
I am getting data from, then I am sending them to a SQL database. Now
the empty string and VB.NET null are different than the SQL Null (type:
"System.DBNull"). So, i need some way of cenverting the values into a
"System.DBNull" object and then send them to the database. Any ideas?

BTW: The parameter called: "ConvertEmptyStringToNull" does not work.
Microsoft said there is a bug and it will be fixed for the release
date.

Thanks,
Kivak Wolf

5. I am having huge problems with a null referance - Asp.Net

6. Java Null VS .NET Null

In Java, creating a class that represents a tuple in a database is relatively 
simple because if you have a field for, lets say, "Quantity" that is an 
integer, you can set it to null.  Since .NET uses a stack for these Value 
Types, the integer (Int32) has an initial value of 0 and you can't set it to 
null.

So, what's the best way to approach this without having to jump through a 
bunch of programmatic hoops?  These are a couple of ways I've though of.

1)  Create a constant that represents a null Int32, et and use that value 
(problem:  you'd have to constantly check that value if you're doing 
calculations)
2)  Make all of your properties be objects.  That way you could set the 
property to an integer, or a null (or DBNull.Value). (problem:  performance 
hit from boxing and potential errors when doing calculations)
3) Have a property for the field and then have an ancillary property names 
"FieldXIsNull"  (problem: classes get bulky and you end up having to check 
the IsNull constantly)

So, what are the best ways to approach this?

Side Note, I'd like to stay away from using datasets because they're big 
memory hogs.  If I can have a class that I can instantiate that keeps track 
of real values, I'll get better memory usage.  As far as the overhead of 
coding all of these classes, I can use/create code generators for that.

7. How to find out which ref-Variable is null, when exception is null reference - .Net Framework

8. Linq weirdness (improperly trying Column = Null instead of Column IS NULL)

Hi,

I have a wierd problem with Linq.  I have the following code in my
fetch method:

        /// <summary>Loads the list.</summary>
        /// <param name="documentHistoryId">The document
        /// for which to get items.</param>
        /// <param name="db">The connection to use.</param>
        /// <param name="taxRate">The tax rate items
        /// should use when loading.</param>
        private void LoadSelf(
            int documentHistoryId,
            decimal? taxRate,
            MedDataDataContext db
        ) {
            var items =
                from lineitems in db.LineItemHistory
                where lineitems.DocumentHistoryId == documentHistoryId
&&
                    lineitems.ParentLineItemId == null
                orderby lineitems.Position
                select lineitems;

            IsReadOnly = false;
            foreach ( var item in items ) {
                LineItemRevision lineRev =
LineItemRevision.GetItem( item, 0, taxRate, db );
                Add( lineRev );

                if ( LoadChildren(
                    documentHistoryId,
                    item.LineItemId.Value,
                    0,
                    taxRate,
                    db
                ) ) {
                    lineRev.IsGroupStart = true;
                }
            }
            IsReadOnly = true;
        }

        /// <summary>Loads the list.</summary>
        /// <param name="documentHistoryId">The document
        /// for which to get items.</param>
        /// <param name="db">The connection to use.</param>
        /// <param name="taxRate">The tax rate items
        /// should use when loading.</param>
        /// <param name="parentLineItemId">The id of
        /// the parent for items to load.</param>
        /// <param name="depth">The depth of the items
        /// being loaded.</param>
        private bool LoadChildren(
            int documentHistoryId,
            int parentLineItemId,
            int depth,
            decimal? taxRate,
            MedDataDataContext db
        ) {
            int childCount;

            var items =
                from lineitems in db.LineItemHistory
                where lineitems.DocumentHistoryId == documentHistoryId
&&
                    lineitems.ParentLineItemId == parentLineItemId
                orderby lineitems.Position
                select lineitems;

            childCount = 0;
            depth += 1;

            foreach ( var item in items ) {
                LineItemRevision lineRev;

                childCount += 1;

                lineRev = LineItemRevision.GetItem( item, depth,
taxRate, db );
                Add( lineRev );

                if ( LoadChildren(
                    documentHistoryId,
                    item.LineItemId.Value,
                    depth,
                    taxRate,
                    db
                ) ) {
                    lineRev.IsGroupStart = true;
                }
            }

            return childCount > 0;
        }

So, you notice that the queries are identical in both LoadSelf and
LoadChildren.  It seems natural that I make LoadSelf simplier by
changing it to this:

        private void LoadSelf(
            int documentHistoryId,
            decimal? taxRate,
            MedDataDataContext db
        ) {
            IsReadOnly = false;
            LoadChildren(
                    documentHistoryId,
                    null
                    -1,
                    taxRate,
                    db
                );
            IsReadOnly = true;
        }

And I make LoadChildren take a Int32? instead of just an Int32.  For
some reason, making these chagnes causes linq to mess up the query.
Instead of specifying ParentLineItemId IS NULL, it tries
ParentLineItemId = Null, which of course never works.

Any ideas?