Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elegant way to avoid NullReferenceException in C#

Tags:

syntax

c#

.net

web

I want to do this

var path = HttpContext.Current.Request.ApplicationPath;

If any of the Properties along the way is null, i want path to be null, or "" would be better.

Is there an elegant way to do this without Ternaries?

ideally i would like this behavior (without the horrible performance and ugliness) string path;

try
{
    path = HttpContext.Current.Request.ApplicationPath;
}
catch
{
    path = null;
}

Thank you

like image 389
AK_ Avatar asked May 30 '12 11:05

AK_


2 Answers

[EDIT]

C# 6 got released a while ago and it shipped with null-propagating operator ?., which would simplify your case to:

var path = HttpContext?.Current?.Request?.ApplicationPath

For historical reasons, answer for previous language versions can be found below.


I guess you're looking for Groovy's safe dereferencing operator ?., and you're not the first. From the linked topic, the solution I personally like best is this one (that one looks quite nice too). Then you can just do:

var path = HttpContext.IfNotNull(x => x.Current).IfNotNull(x => x.Request).IfNotNull(x => x.ApplicationPath);

You can always shorten the function name a little bit. This will return null if any of the objects in the expression is null, ApplicationPath otherwise. For value types, you'd have to perform one null check at the end. Anyway, there's no other way so far, unless you want to check against null on every level.

Here's the extension method used above:

    public static class Extensions
    {
    // safe null-check.
    public static TOut IfNotNull<TIn, TOut>(this TIn v, Func<TIn, TOut> f) 
            where TIn : class  
            where TOut: class 
            { 
                    if (v == null) return null; 
                    return f(v); 
            }       
    }
like image 169
Patryk Ćwiek Avatar answered Oct 11 '22 06:10

Patryk Ćwiek


UPDATE (November 2014)

C# 6 contains something called the Null Propagation Operator, which means that there is language support for this. Your example can be written as follows in C# 6:

var path = HttpContext?.Current?.Request?.ApplicationPath;

If any of the parts contains null, the complete expression will return null.


You can write something like this:

string value = NullHelpers.GetValueOrNull(
    () => HttpContext.Current.Request.ApplicationPath);

The simplest way to implement this NullHelpers.GetValueOrNull is probably something like this:

public static T GetValueOrNull<T>(Func<T> valueProvider) 
    where T : class
{
    try
    {
        return valueProvider();
    }
    catch (NullReferenceException)
    {
        return null;
    }
}

But by far the coolest way to solve this is by using Expression trees:

public static T GetValueOrNull<T>(
    Expression<Func<T>> valueProvider) 
    where T : class
{
    var expression = (MemberExpression)
        ((MemberExpression)valueProvider.Body).Expression;

    var members = new List<MemberExpression>();

    while (expression != null)
    {
        members.Add(expression);

        expression = 
            (MemberExpression)expression.Expression;
    }

    members.Reverse();

    foreach (var member in members)
    {
        var func = Expression.Lambda<Func<object>>(member).Compile();

        if (func() == null)
        {
            return null;
        }
    }

    return valueProvider.Compile()();
}

This is also the slowest way to do things, since each call will do one or multiple JIT compiler invocations, but...

It is still cool ;-)

like image 24
Steven Avatar answered Oct 11 '22 07:10

Steven