10

What is the most efficient way to check for null references on objects? I have seen various code samples that have different ways of checking so of the following which is the most efficient or the one that it is considered best practice to use?

Object.ReferenceEquals(item, null)

item == null

item != null

Object.Equals(item, null)

thanks

Manatherin
  • 4,169
  • 5
  • 36
  • 52
  • 4
    Suppose one of these were 10 times slower than the others, and you used it. Would you notice? Only if it were in a rare costly hotspot. – Mike Dunlavey Jan 31 '11 at 14:07
  • 1
    @MikeDunlavey: Of course, it would be utterly moronic to choose the one which is 10x slower over any of the other options presented (assuming the other options are semantically correct). Optimization is not premature if the alternative would be boneheaded and would carry with it no added benefit. – Ed S. May 01 '13 at 05:13
  • 2
    @EdS.: Maybe it's moronic and boneheaded, but people do it all the time, and it's really OK, if it's in code where performance is not an issue. Whenever people `new` anything, they're spending buckets of cycles, and if they use an interpreted language, they're paying 1-2 orders of magnitude speed ratio. – Mike Dunlavey May 01 '13 at 14:01
  • @MikeDunlavey: People do a lot of dumb things all the time, it doesn't make it ok. You can't compare using new in C# since it is mandatory. Developers/engineers who don't understand the implications of the code they are writing are incompetent. – Ed S. May 01 '13 at 19:05
  • I would side with the folks who say to use == and !=. The compiler might be converting that syntax to Object.Equals(item, null) or ReferenceEquals( item, null) or something else (changing code is what compilers do, after all), but clarity is your first priority unless you have profiled your running code and know you have a performance problem – Craig Tullis Sep 16 '16 at 23:48

7 Answers7

9
  1. Object.ReferenceEquals(item, null) compare references and equals to item == null.
  2. Object.Equals(item, null) compare references for reference types and bitwise for value types, but in reflector it's equal to (item == null) || ((item != null && null != null) && item.Equals(null)).
  3. item != null code not always equals to !(item == null), but of course result should be equal.
  4. item == null code not equals to null == item, it's similar to typeof(item).Equals(object) and object.Equals(typeof(item)) method calls.

It differ because you can override !=, ==, Equals. Use methods with known implementation, null == item is better to code, but harder to read. Object.ReferenceEquals(null, item) may be faster or not.

P.S. use string.IsNullOrEmpty(item) too

Quiz
  • 514
  • 1
  • 7
  • 13
  • `null == item` is *not* harder to read, and in many c-style languages it is a better practice because the habit eliminates the possibility of making an assignment when a comparison is intended. Of course the C# compiler barks at you if you try to make an assignment in a conditional. But I'd still argue that it's a good practice. I haven't benchmarked, but in point #4, while not identical, the comparisons are certainly equivalent and all the same operations are performed, so I would be pretty surprised if there is a performance difference. – Craig Tullis Sep 16 '16 at 23:31
7

For comparing to null, I'd use == or != always, because for null it should always give the same result as ReferenceEquals and Equals anyway (so no need for the extra code).

Edit: It's true that == could be overridden to give a wrong result for null (i.e., true) but that means the override is buggy. To make the code readable I would stick with == and !=.

sinelaw
  • 16,205
  • 3
  • 49
  • 80
  • 1
    -1, not always. It can be different from .ReferenceEquals if those operators are overloaded (in a meaningless way of course) – nawfal Dec 16 '12 at 07:39
  • nawfal, of course you're right - it is possible only in a meaningless (incorrect) override of the `==` operator. I'd rather rely on `==` not being bogus, and be able to write much more readable code (e.g. `null != obj` as opposed to `false == Object.ReferenceEquals(obj, null)`) – sinelaw Dec 16 '12 at 19:12
  • but you never know. And the above code can be condensed to `!ReferenceEquals(obj, null)`, or even better an extension method. Just saying. – nawfal Dec 16 '12 at 19:14
  • 1
    No big argument here, but an extension could be just as wrong. The question is where you draw the line. – sinelaw Dec 16 '12 at 19:24
  • Yes it is, but I think an extension method is safe as you move the custom null checks to a method with that intent. overloading is much more common. I realise your point. Let me edit your post to cancel my vote – nawfal Dec 16 '12 at 19:31
  • Another problem would be when you use `==` for null checks inside overloading of `==` operator of a class. That [causes infinite recursion](http://stackoverflow.com/questions/73713/how-do-i-check-for-nulls-in-an-operator-overload-without-infinite-recursion). To have one consistent style and be always safe I prefer mine. – nawfal Feb 04 '13 at 09:15
6

Updated answer

As of C# 7.0 is you can use:

item is null

should be the simplest and most foolproof way. It's same as ReferenceEquals check.


Old answer:

1)

Object.ReferenceEquals(item, null)

This is a good way. Not as concise as I would love, but still great and tells u the intent exactly.

2)

item == null

item != null

There is nothing wrong with this (which is the most elegant) if you are sure == and subsequently != is overloaded correctly. Its easy to write (overload) bad equality operators (and often done). But the real trouble is when you are trying to overload == operator in a class (lets say of value semantic). You cant use == for null checks inside == overloading function of the class since that will cause an infinite recursion. To have one consistent style, I rely on something else.

3)

Object.Equals(item, null)

Again it internally does a ReferenceEquals so there is not much point, but if it semantically makes more sense to you, then go with this.

4)

My approach is to do

(object)item == null

upon which I'm relying on object's own equality operator which can't go wrong. Not so readable so I just wrap in a custom extension method and an overload:

public static bool IsNull<T>(this T obj) where T : class
{
    return (object)obj == null;
}

public static bool IsNull<T>(this T? obj) where T : struct
{
    return !obj.HasValue;
}

It makes more sense since I will need to check against DBNulls too often. So now I have one consistent style all over!

public static bool IsNull<T>(this T obj) where T : class
{
    return (object)obj == null || obj == DBNull.Value;
}

(Do not take off the (object) casting as that's what will prevent infinite recursion when overloading == as stated before)

Additionally the constraint prevents IsNull on value types. Now its as sweet as calling

object obj = new object();
Guid? guid = null; 
bool b = obj.IsNull(); // false
b = guid.IsNull(); // true
2.IsNull(); // error

I also have found (object)item == null is very very very slightly faster than Object.ReferenceEquals(item, null) or object.Equals(,) for that matter, but only if it matters (I'm currently working on something where I've to micro-optimize everything!).

To see a complete guide on implementing equality checks, see What is "Best Practice" For Comparing Two Instances of a Reference Type?

nawfal
  • 70,104
  • 56
  • 326
  • 368
3

ReferenceEquals is equivalent to (object)o1==(object)o2. It may be faster than o1==o2 if the equality operator is overloaded. Object.Equals is probably a bit slower.

The difference between == and != isn't performance, but how your program should look like. They can be a bit slower if the == and != operator are overloaded.

But I don't think the performance difference between them matters at all. I'd choose the one that's easiest to read. And that's usually == or !=.

If I throw an exception I usually use == as in:

if(o == null)
  throw new ...;

If null results in a no-op then usually != is appropriate

if(x != null)
{
   ...
}
CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
  • Hmm. `ReferenceEquals` being equivalent to `(object)o1==(object)o2` relies on explicit knowledge that the System.Object data type's comparison operator does a reference comparison. Sure, maybe a good programmer should know that. But it feels kind of "clever" and therefore slightly obscure if you're scanning the code for comprehension. I don't mean disrespect by saying that, but I would favor clarity over clever whenever it's reasonable. – Craig Tullis Sep 16 '16 at 23:43
3

As an extra, don't forget code contracts in .NET 4.0!

System.Diagnostics.Contracts.Contract.Requires(item != null);

Which is not only nice and clear, but allows compile time checking. See Code Contracts in msdn.

Massif
  • 4,327
  • 23
  • 25
2

I always use

item != null

but this is harder to read than

item == null

Object.ReferenceEquals is used to check whether two objects are the same instance.

WraithNath
  • 17,658
  • 10
  • 55
  • 82
  • 1
    How do you figure `!=` is harder to read than `==`? – Cody Gray - on strike Jan 31 '11 at 11:01
  • 1
    Depending on what font you use the exclamation mark is less visible that an equals sign. eg these are less pixels in ! than = if for example you used in (!bool) is easier to miss than (bool==false) depends on whether you have any visually impaired staff or not I suppose! – WraithNath Jan 31 '11 at 11:04
  • 1
    If that's *ever* been a problem for you, it sounds like you need to switch fonts in your IDE. – Cody Gray - on strike Jan 31 '11 at 11:06
  • Its not a problem for me, its something I have picked up when reading articles on code readability. I use the Droid font, I would change it if I was unable to read my own code :p http://code.google.com/webfonts/family?family=Droid+Sans+Mono – WraithNath Jan 31 '11 at 11:11
  • It could be that other members on the team are using fonts in which some things are more visible than others. – ftvs Aug 16 '12 at 06:41
  • 1
    I favor `null == item`, because in so many languages if the programmer slips and says `item=null`, the compiler will happily make an assignment and return true instead of performing a comparison. But `null = item` is invalid in every language and essentially all compilers will catch it. – Craig Tullis Sep 16 '16 at 23:46
-1

First 2 are the same effectively.

The last however does not only do a reference check, and should not be used for null checking.

leppie
  • 115,091
  • 17
  • 196
  • 297