1

I'm pulling all of the advanced features together for this one, but haven't worked with generics or lambda expressions very much:

Here's example usage of the method I want to create:

MyClass mc = null;
int x = mc.TryGetOrDefault(z => z.This.That.TheOther); // z is a reference to mc
// the code has not failed at this point and the value of x is 0 (int's default)
// had mc and all of the properties expressed in the lambda expression been initialized
// x would be equal to mc.This.That.TheOther's value

Here's as far as I've gotten, but I'm not sure what to do with this expression object.

[enter image description here1

Ronnie Overby
  • 45,287
  • 73
  • 267
  • 346
  • Yeah, turns out it was the firewall here blocking it... Doh... – James Michael Hare Jul 19 '11 at 20:23
  • mc is null - I am not sure what you try to achieve... what happens when you assign mc before using that expression ? – Yahia Jul 19 '11 at 20:29
  • thats the point. if mc is null or any other exception gets thrown i get the default of TResult. Otherwise i get what I'm after. – Ronnie Overby Jul 19 '11 at 20:30
  • Why are you using an expression tree in the first place, instead of just a delegate? It's still not really clear what the precedence is - do you want the lambda to be called at all if `obj` is non-null? – Jon Skeet Jul 19 '11 at 20:31
  • I think he wants to be able to pass in an expression that selects an object's properties (or property of property etc), and have it handle null values all along the way. Similar to the `With` extension method that @Jon's done (but i can't find). – George Duckett Jul 19 '11 at 20:33
  • I want to save myself from doing null value checks. I don't care whether I pass in delegate or expression tree or a pepperoni pizza as long as I can call the code in my example. – Ronnie Overby Jul 19 '11 at 20:34

3 Answers3

1

Is this the sort of thing you're after?

public static TResult TryGetOrDefault<TSource, TResult>(this TSource obj, Func<TSource, TResult> expression)
{
    if (obj == null)
        return default(TResult);

    try
    {
        return expression(obj);
    }
    catch(NullReferenceException)
    {
        return default(TResult);
    }
}
DaveShaw
  • 52,123
  • 16
  • 112
  • 141
  • There's also some idea's here : http://stackoverflow.com/questions/4958133/null-coalescing-within-an-invocation-chain – DaveShaw Jul 19 '11 at 20:51
0

What you are trying to do sounds like Maybe.

Project Description:

Maybe or IfNotNull using lambdas for deep expressions in C#

int? CityId= employee.Maybe(e=>e.Person.Address.City);

Update: There is more discussion about how best to accomplish this sort of thing at this question.

Community
  • 1
  • 1
Gabe Moothart
  • 31,211
  • 14
  • 77
  • 99
0

Here's what I was after:

    public static TResult TryGetOrDefault<TSource, TResult>(this TSource obj, Func<TSource, TResult> function, TResult defaultResult = default(TResult))
    {
        try
        {
            defaultResult = function(obj);
        }
        catch (NullReferenceException) { }
        return defaultResult;
    }
Ronnie Overby
  • 45,287
  • 73
  • 267
  • 346