Elegant way to avoid NullReferenceException in C#

前端 未结 4 2004
傲寒
傲寒 2020-12-18 03:09

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

4条回答
  •  一整个雨季
    2020-12-18 04:07

    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(Func 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(
        Expression> valueProvider) 
        where T : class
    {
        var expression = (MemberExpression)
            ((MemberExpression)valueProvider.Body).Expression;
    
        var members = new List();
    
        while (expression != null)
        {
            members.Add(expression);
    
            expression = 
                (MemberExpression)expression.Expression;
        }
    
        members.Reverse();
    
        foreach (var member in members)
        {
            var func = Expression.Lambda>(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 ;-)

提交回复
热议问题