Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is good practice for null reference checks? [duplicate]

Tags:

performance

c#

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

like image 912
Manatherin Avatar asked Jan 31 '11 10:01

Manatherin


People also ask

Is it good practice to check for null?

Avoiding Null Checks Through Coding PracticesIt's usually a good practice to write code that fails early. So, if an API accepts multiple parameters that aren't allowed to be null, it's better to check for every non-null parameter as a precondition of the API.

Are null checks bad?

Generally speaking, returning null from a method should be considered really bad. This forces the user of the method to do null checks and create conditional code paths.


3 Answers

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 !=.

like image 79
sinelaw Avatar answered Oct 31 '22 19:10

sinelaw


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?

like image 30
nawfal Avatar answered Oct 31 '22 21:10

nawfal


  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

like image 21
Quiz Avatar answered Oct 31 '22 19:10

Quiz