tags:

views:

49

answers:

4
+1  Q: 

Lambda Expressions

Is there a better way to avoid NullRefenrenceException other than try/catch

i.e

x => x.Child.GChild.GChildProp1

If Child Or GChild happen to be null obviously this would raise NullRefenrenceException

other solution that popped into the head, is to evaluate each expression part individually from left ?

which would be better or it there a better solution ?

+2  A: 

Well, you could convert that into an expression tree instead of into a delegate, and carefully navigate it. But no, C# doesn't have anything like a "null-safe dereferencing operator". I gather the C# team has looked into it, and found it hard to come up with something which actually works the way you'd naturally want it to. That's not to say they won't have another look at a later date, of course :)

(It certainly sounds like a relatively easy language feature to implement... but I trust the team when they say there are hidden complexities!)

I wouldn't really want to catch a NullReferenceException as a way round this though... I'd prefer to write a method which checked for null references explicitly for the particular case. It depends on your situation though.

Jon Skeet
cheers for that jon, just bought your book yesterday !
kalki
@Jon, can i tempt you back in to give an opinion on my answer, more for my benefit than @kalki's? I can't pass up the opportunity to learn something if you have the time :)
slugster
A: 

If you want a single expression, you could use a generic method that can handle null references without causing an exception:

public static R TryGet<T,R>(T obj, Func<T,R> getProperty) {
  if (obj == null) {
    return default(R);
  } else {
    return getProperty(obj);
  }
}

Now you can use that to try to get a property:

x => TryGet(TryGet(TryGet(x, y => y.Child), y => y.GChild), y => y.GChildProp1);

If you get a null reference on the way, you end up with the default value of the final property (which is null if it's a reference type).

Guffa
thanks for that guffa, but rather hard on the eye :)
kalki
@kalki: Well, given the task, I think that it's as elegant as you can get it. :) If you try it on anything more complicated like `x.Child.Child.Child.ChildProp` it's actually shorter than using conditional operators to check each step, not to mention `x.Child.Child.Child.Child.Child.Child.ChildProp`...
Guffa
A: 

Hmmm, is there anything fundamentally wrong with this?

myList.Where(x => x.Child != null && x.Child.GChild != null).Select(x => x.Child.GChild.GChildProp1);

or:

var z = from x in myList
        where x.Child != null && x.Child.GChild != null
        select x.Child.GChild.GChildProp1;

Note there was no null check on the third property in the heirarchy as i presume it is okay to select those that are null.

I'm mainly throwing this out there because Jon's answer interests me and i want him to explain more about changing this to an expression tree - mainly because i don't like popping out to a separate function in the middle of a linq expression unless i really have to (just personal preference, others may have a different opinion :)

slugster
There's nothing wrong with it in that it'll work... although it depends on whether you want to get "null" for *any* items that have null somewhere in the chain. It's also pretty longwinded when you *really* only want to have to right the full expression once. One *final* potential issue - it will evaluate Child three times, and Child.GChild twice. Not an issue in most cases, but *could* produce odd results in some cases.
Jon Skeet
Cheers @Jon, appreciated.
slugster
A: 

Exceptions should only be thrown in exceptional cases i.e. in cases you can't possibly account for (i.e. out of memory etc.). Using try/catch for cases like above is considered bad practice (for performance and degbuggability reason etc) and can be avoided by checking for null references i.e.

x => { if (x.Child != null && x.Child.GChild != null) x.Child.GChild.GChildProp1; };

Best regards, Christian

Christian