Nullsafe Navigation in C #

Possible duplicates:
Safe navigator in C #?


Label for "null if the object is null, or object.member if the object is not null

in my XML processing project, I need to navigate the chained property to get the desired value. For example, obj1.obj2.obj3.obj4.obj....Value . and it is possible that any object in this chain is null.

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

  • Option1 (using the logic explained in 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; } 
  • Option 3:

     //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 } 
+6
source share
4 answers

I would definitely not go with the try-catch option. This is not only a code smell (exception-based development), but if you are concerned about performance, handling exceptions is not an option.

I do not quite understand the second option. Could you hang this wherever you want to access the Value property? Or is it in the extension method.

Option one looks the cleanest.

About performance: I don’t think you will find big differences between options 1 and 2, but you can try it in a small console project. Just run the first and second options, say 1000 times and calculate the time it takes. Not an exact science, but usually good enough to measure differences in performance.

I assume that you will not see much difference. I think you are practicing micro-optimization . If you are not going to work in a system where it is really important, go to the solution that seems most elegant to you.

+3
source

I am for option number 2.

Option # 1: If Obj1 is NULL, he will continue to check for null for Obj2, Obj3, Obj4 and Obj5 every time! At least with Option # 2, once it finds that Obj1 is NULL, it does not check the rest of the if statement, which means fewer processing cycles.

Option number 3, of course, is bad. Capturing exceptions is overhead, and if you repeat thousands of nodes, you will feel it - ignore the smell.

My concern is that you may be asking the wrong question. You declare that you use XML, then these objects are really elements, right?

Perhaps if you formulated your question differently and provided more information about the structure of the XML document, we could write a Linq query to pull the value out without all the hard-coded null checks (and the loops that I assume you are also using).

+1
source

Are you sure option 2 is so bad? A try / catch block does not affect performance if the catch block does not throw any exception to the caller (this is the exception throwing mechanism that is the producer).

Here is a quote:

Search and design exception-heavy code can lead to a decent first-win victory. Keep in mind that this has nothing to do with try / catch blocks: you only incur expenses when the actual exception. You can use as many try / catch blocks as you want. Using exceptions is free of charge where you lose sight. For example, you should avoid things like using exceptions for control flow.

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

Obviously, design No. 3 does not allow you to continue evaluating until you find zero somewhere in the chain, for example, project No. 1, and also prevent a heavy inconvenient code similar to design No. 2.

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

+1
source

I would use a node structure so you can do this:

 var hasNullValue = false; var x = string.Empty; var node = firstNode; while (node.Child != null) { // On the first hit we set the null flag // and break out of the loop if (node.Value == null) { hasNullvalue = true; break; } node = node.Child; } if (!hasNullValue) x = node.Value; 
0
source

Source: https://habr.com/ru/post/888878/


All Articles