7

I have been looking around finding the best possible option for handling null objects in calling a method (or method chain).

It is our common practice to check with if condition:

if ( customObject != null ) {
    customObject.callMe();
}

Which can be further improved by using extension methods:

Program customObject = null;
if (customObject.NotNull()) {
    customObject.CallMe();
}

public static bool NotNull(this object o) {
    return o == null;
}

PLEASE NOTE: I normally ignore ! from my programming practice. Hence it is wise to say that for me extension methods are good to go.

However, it becomes very complicated in dealing with when the Method chain is involved.

customObject.CallMe().CallMe2() ex... 

How you do think it can be handled in C#, so that the CallMe is called only if customObject is not null and CallMe2 is called only if CallMe returns non null object.

Of course I can use If conditions or ternary operator. However, I would want to know if vNext, C#5.0 has some thing to offer.

8
  • 6
    In which way, using NotNull() is an improvement? Commented Aug 31, 2014 at 23:52
  • by getting extension method to play with actual condition I can control what I define as Null hence there is an improvement. ( I normally ignore ! from my programming practice ).
    – codebased
    Commented Sep 1, 2014 at 0:00
  • you might want to look into the Null Object Pattern Commented Sep 1, 2014 at 0:01
  • at least if(myObject != null) is a clear code. I'm not sure that using a pattern to avoid this kind of code will help the next programmer who will take your code. Commented Sep 1, 2014 at 0:05
  • 1
    programmers.stackexchange.com/questions/12777/…
    – dwerner
    Commented Sep 1, 2014 at 0:07

6 Answers 6

17

In the upcoming C# 6 (vNext) has the ?. operator (Null Conditional Operator) which easily allow you to chain null reference checks for every nested property.

An example of this would be:

int? first = customers?.[0].Orders?.Count();

This was a requested feature in the Visual Studio UserVoice site

Add ?. Operator to C#

You can see the status for all the new language features for C# 6.0 on the Codeplex site for Roslyn:

C# 6 Language Features Status

2
  • pretty stoked for the new features coming out Commented Sep 1, 2014 at 0:21
  • Ok it make sense now that currently there is no way so I am accepting this as my answer because this is exactly what I was looking for. I did heard about ?. but did not gave much attention to it. Thank you Scott
    – codebased
    Commented Sep 1, 2014 at 0:39
4

You can currently write these kinds of extension methods:

public static class Extensions
{
    public static R IfNotNull<T, R>(this T @this, Func<T, R> @select) where T : class
    {
        return @this.IfNotNull(@select, () => default(R));
    }

    public static R IfNotNull<T, R>(this T @this, Func<T, R> @select, Func<R> @default) where T : class
    {
        return @this != null ? @select(@this) : @default();
    }

    public static void IfNotNull<T>(this T @this, Action<T> @action) where T : class
    {
        if (@this != null)
        {
            @action(@this);
        }
    }
}

Then call them like so:

customObject 
    .IfNotNull(y => y.CallMe())
    .IfNotNull(y => y.CallMe2());
2

C# 5 has nothing to offer to simplify your code. You are stuck with either:

  • Nested if conditions
  • Complicated ternary expressions
  • Englobing try/catch catching NullReferenceException (you really shouldn't do that if a null in your chain is not really exceptionnal, i.e. it should not happen, but you want a keepsafe).

However, the future may be brighter, as the null-propagating operator ?. is a proposed feature of C# 6, and has already be implemented is Roslyn, so it would be a great surprise if it was not effectively in C# 6. With this operator, you will be able to write

customObject?.CallMe()?.CallMe2()?.[...] 

And the compiler will create the nested if for you (and even ensure that every method is only called once). So, A little more patience...

7
  • How on earth is this any better than an exception? It is basically a way of automatically eating exceptions. You are trying to just ignore the returned null and clip the execution chain, without addressing the logical error. Commented Sep 1, 2014 at 0:26
  • 1
    @JonJayObermark it is WAY better than eating an exception, because the new operator NEVER rises an exception. It's NOT a try/catch. It's evaluate the expression, check if the result is null, call the method/property/field if it's not and return null otherwise. There is no logical error in there, other than the one allowing null references in the language in the first place. This may be a design error (I do believe it is), but at least now we have a new tool to deal with this fault more easily.
    – Falanwe
    Commented Sep 1, 2014 at 10:03
  • OK, but then do you expect not to have to check if lists are empty, or if various other unexpected things are happending. Any null you have not chosen by design to make meaningful is really an exception whether or not you treat it as such. Commented Sep 1, 2014 at 14:45
  • @JonJayObermark The ?. operator will not by any mean give you the semantic of the null it may have. The meaning of the null is still depending on your business logic. I expect the most common use case will be var myValue = someVariable?.SomeProperty ?? defaultValue;
    – Falanwe
    Commented Sep 1, 2014 at 14:55
  • @JonJayObermark Whatever happens, it is NOT really an exception. An exception is something pretty grave. It interrupts the execution flow. It messes with the stack. It's very costly performance-wise. It will make debuggers break with the right configurations. It will produce log messages. All things you may want to avoid with a simple sanity check. The ?. operator does this sanity check, and not much more.
    – Falanwe
    Commented Sep 1, 2014 at 14:59
1

Since people are tearing apart the answer that assumes you aren't an idiot, here is one that assumes you are.

You should have checked when customObject was created, because that is the point at which you would have know why you got a null. If you didn't check then, your best bet now is to let your code throw the exception. If there is still something you can do that makes perfect sense without having the object you clearly need, you can fix that up in the catch of the exception, but there probably isn't.

All of the mechanisms that ignore the significance of an unexpected null are just passing along the failure to have paid attention earlier, including habitual overuse of the proposed null-propagation operator, and all habits of checking objects before use. They are seeking an efficient response to a catastrophe that minimizes attention paid to it.

If you are signalling important information with the nullness of an object, that is probably a bad design choice, and you should have converted the null into more usable information when it was introduced.

Testing for the unexpected nullness of an object right before it is used, rather than right after it is produced cannot really help anyone. It is a code-smell that indicates you have misplaced responsibility, probably in one of these ways:

  1. You are unwilling to challenge people who make awkward design decisions without adequate explanation
  2. You do not feel you have control over something you have incorporated but are too lazy to wrap it
  3. You don't believe nulls should exist, and you are trying to ignore them, so you haven't thought through any policy on them.

The policy you indicate, of eating the null and continuing execution without analyzing it, is a bad one. If you intend to keep it, that is my other answer. You should instead do something reasonable.

In a lot of workplaces, putting an empty catch block anywhere is a clear documentation of future work. So it is doing something. But leaving it there is never an option that should stand in good code. Such a block would more reasonably convert the exception into a response that creates future work to fix the source of the error, even if the code-block implements a workaround that addresses the problem in a more local way.

1
  • This exactly. If your reference is null, and your code doesn't call the required method because of these misguided null checks, you will get a far worse and harder to diagnose failure later on.
    – kaalus
    Commented Mar 20, 2023 at 14:00
0

C# 6 does have the ? operator, otherwise you can look into monads, particularly the Maybe monad, e.g. here, here, elsewhere. Is it worth using monads in a non-functional language that wasn't designed with them in mind is a different question.

3
  • IEnumerable, Nullable, Func, Lazy and a few other built-in types make me believe it IS worth it ;) In fact, most of the newer and most appealing langugage features of C# relate to monads or comonads (Task...)
    – Falanwe
    Commented Sep 1, 2014 at 10:07
  • @Falanwe agree, but getting my head around monads as a concept wasn't easy since I'm not too familiar with functional languages and I wouldn't bother to just get around a few if (foo == null) blocks in this case. Commented Sep 1, 2014 at 10:13
  • A very good thing about monads is that you don't really need to understand them to use them. And when you do understand them, it opens such a wide field of possibilities...
    – Falanwe
    Commented Sep 1, 2014 at 11:33
-6

This is the point of exception handling. If you want to respond to unusual circumstances like getting an unexpected null returned from a function, then catch the NullReferenceException, and call your recovery code from there. The exception itself will stop further calls, so if that is all you wish to accomplish, implement no recovery code. I do not suggest this is a reasonable response, something like this should generally at least be logged.

try
{
    customObject.CallMe().CallMe2()
}
catch (NullReferenceException ex)
{
   /* save enough details to determine why you got an unexpected null */
}

Do not use exception handling to accomplish normal programming tasks, but do not avoid it excessively, by checking for every possible contingency, no matter how rare. Decide what failures are likely in your code (that you can do anything about) and include a healthy list of catch'es at the end of each reasonable-sized block.

16
  • 11
    -1: absolutely not. NullReferenceException almost always represents a bug in your code. It should never be "handled" - it should be fixed. Commented Sep 1, 2014 at 0:11
  • 1
    Most exceptions represent thing that should be fixed. But fixing them immediately during a run is not practical. So exceptions exists so they can be logged and worked around. Like I said, don't use them on purpose to control flow, but if the mechanism had no use, it would not exist. Checking for null all the time is not a better solution, as the null return is just as likely to be a bug. Commented Sep 1, 2014 at 0:14
  • 1
    You're totally wrong. The mechanism doesn't exist for you to ignore exceptions. It exists so that you are informed of the bug in your code and can fix it ASAP. Or are you of the opinion that programs must never crash? Commented Sep 1, 2014 at 0:16
  • 2
    I have seen very few cases of NullReferenceException which are actually exceptional. Most are due to developers who do not know what null means, so don't check for it, or who are unaware of the possibility that null might be returned. In these cases, the best thing is usually for the program to crash immediately, informing their supervisors of this fact. Commented Sep 1, 2014 at 0:20
  • 2
    @codebased That is exactly why this site provides a "downvote" option - for when you don't feel like the answer is correct. I too disagree with this answer - there are so many other factors involved. A simple null check is far and away more performant than allowing an exception to be thrown and the stack to be walked. NullReferenceExceptions are always fixable without catching them - I would reject any code I reviewed that expected a NullReferenceException and attempted to handle it in a catch. Commented Sep 1, 2014 at 1:08

Not the answer you're looking for? Browse other questions tagged or ask your own question.