Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nullsafe navigation in c# [duplicate]

Tags:

c#

.net

null

linq

Possible Duplicates:
Safe Navigation Operator in C#?
Shortcut for “null if object is null, or object.member if object is not null”

in my XML processing project, i have to navigate through chained property to get the desired value. e.g, obj1.obj2.obj3.obj4.obj....Value. and it is quit possible that any of the object in this chain is null.

I googled for "NullSafe Navigation in c#" and found some nice articles. From one of the Post, I got an idea to implement Custom Extension. Now I have a question regarding the performance about this extension. I have these 3 solution. can anyone suggest me which one is the best to adopt (in terms of performance)?

  • Option1 (using logic explained on this article):

    //custom extension method
    public static TOutput IfNotNull<TInput, TOutput>(this TInput x, Func<TInput, TOutput> f)
        where TInput : class
        where TOutput : class
    {
        return x == null ? null : f(x);
    }
    
    //with custom extension method -- Very neat & clean.. but what about performance? 
    string x = obj1
                .IfNotNull(x => x.obj2)
                .IfNotNull(x => x.obj3)
                .IfNotNull(x => x.obj4)
                .IfNotNull(x => x.obj5)
                .IfNotNull(x => x.Value);
    
  • Option2:

    //with NullCheck  -- probably right way?
    if(obj1 != null 
        && obj1.obj2 != null 
        && obj1.obj2.obj3 != null 
        && obj1.obj2.obj3.obj4 != null
        && obj1.obj2.obj3.obj4.obj5 != null)
    {
        string x = obj1.obj2.obj3.obnj4.obj5.Value;
    }
    
  • Option3:

    //with try-catch.. With lowest cyclomatic complexity, but not a right approach.
    try
    {
        string x = obj1.obj2.obj3.obnj4.obj5.Value;
    }
    catch(NullReferenceException ne)
    {
        //ignore exception
    }
    
like image 460
Nirmit Shah Avatar asked May 24 '11 06:05

Nirmit Shah


People also ask

Can I use null safe operator?

Null-safe operator is a new syntax in PHP 8.0, that provides optional chaining feature to PHP. The null-safe operator allows reading the value of property and method return value chaining, where the null-safe operator short-circuits the retrieval if the value is null , without causing any errors.

What does safe navigation operator do?

Use the safe navigation operator ( ?. ) to replace explicit, sequential checks for null references. This operator short-circuits expressions that attempt to operate on a null value and returns null instead of throwing a NullPointerException.

What is the safe navigation operator in c#?

C# 6.0 includes a new null-conditional operator (sometimes called the Safe Navigation Operator): In previous versions null checking for any kind of objects manually we need to write if condition then we need to write our required properties or else we need to write our business logic.

What does safe navigation operator return?

In object-oriented programming, the safe navigation operator (also known as optional chaining operator, safe call operator, null-conditional operator, null-propagation operator) is a binary operator that returns null if its first argument is null; otherwise it performs a dereferencing operation as specified by the ...


3 Answers

I'd definitely not go with the try-catch option. Not only is this a code-smell (exception driven development), but if you're worried about performance, exception handling is not the way to go.

I don't quite understand the second option. Would you have to put that everywhere you want to access the Value property? Or is that in an extension method.

Option one looks the cleanest.

About performance: I don't think you'll find big differences between option 1 and 2, but you could try it out, in a small Console Project. Just run the first and the second option, say, 1000 times and calculate the time it takes. Not exact science, but usually good enough to measure performance differences.

I'm guessing you won't see a very big difference. I'm thinking you're practicing micro-optimization. Unless you're going to run on a system where this really is important, go with the solution that seems most elegant to you.

like image 124
Peter Avatar answered Sep 24 '22 01:09

Peter


I'm for option #2.

Option #1: If Obj1 is null, then it will continue to check for null for Obj2, Obj3, Obj4, and Obj5 every time! At least with Option #2, as soon as it finds that Obj1 is null, it doesn't bother checking the rest of the if statement - and that means less processing cycles.

Option #3 is of course bad. Catching exceptions is overhead, and if you're recurisely going through thousands of nodes, you're gonna feel it - never mind the smell.

My concern is you might be asking the wrong question. You state you're using XML, then these Objects are really Elements, right?

Maybe if you phrased your question differently and gave more information about the XML document structure, we could write an Linq query to pull the value without all the hard-coded null checks (and loops that I'm assuming you're also using).

like image 21
MikeTeeVee Avatar answered Sep 24 '22 01:09

MikeTeeVee


Are you so sure that Option 2 is so bad ? A try/catch block doesn't affect the performance as long as the catch block doesn't throw any exception to the caller (it is the exception throwing mechanism which is performance eater).

Here is a citation :

Finding and designing away exception-heavy code can result in a decent perf win. Bear in mind that this has nothing to do with try/catch blocks: you only incur the cost when the actual exception is thrown. You can use as many try/catch blocks as you want. Using exceptions gratuitously is where you lose performance. For example, you should stay away from things like using exceptions for control flow.

taken from http://msdn.microsoft.com/en-us/library/ms973839.aspx

Obviously design #3 prevents to go on with evaluating as long as you found a null somewhere in the chain like design #1, and also prevents from a heavy awkward code writing like design #2.

I think the try/catch design is worth considering...

like image 37
Ssithra Avatar answered Sep 23 '22 01:09

Ssithra