Maybe there is more

Michel Perfetti, has taken my little Maybe thingie and gone a lot further,

by using expression tree re-writting he has made it possible to express this:

string code = licensePlate.Maybe(lp => lp.Car)
                          .Maybe(c => c.Owner)
                          .Maybe(o => o.Address)
                          .Maybe(a => a.PostCode);

which is NULL safe but very cumbersome like this:

string code = licensePlate.Maybe2(lp => lp.Car.Owner.Address.PostCode);

which is much cleaner and still NULL safe. 

Michel does this by declaring Maybe2 to take an Expression, rather than a Func i.e. it has this signature: public static V Maybe2<T, V>(this T t, Expression<Func<T, V>> expression)

Then he cracks open the expression and rewrites it to do each property access inside a call to Maybe.

Nice stuff Michel.

UPDATE: Sorry for originally getting your last name wrong Michel, and thanks Matthieu for pointing it out!

Comments (3)

  1. says:

    I just had to try this one step further 😛

       public static class Null


           private static readonly MethodInfo maybeMethod;

           static Null()


               maybeMethod = typeof(Null).GetMethod(“Maybe”, BindingFlags.Public | BindingFlags.Static);


           public static V Maybe<T, V>(this T t, Func<T, V> selector) where T : class


               return t != null ? selector(t) : default(V);


           public static T Try<T>(Expression<Func<T>> ex)


               MemberExpression memberBody = ex.Body as MemberExpression;

               if (memberBody != null)


                   MethodCallExpression result = ConvertMemberToMethodCall(memberBody);

                   LambdaExpression lambda = Expression.Lambda(result);

                   return (T)lambda.Compile().DynamicInvoke();


               throw new NotSupportedException();


           private static MethodCallExpression ConvertMemberToMethodCall(MemberExpression memberExpression)


               MemberExpression me = memberExpression.Expression as MemberExpression;

               Expression ex = me != null ? ConvertMemberToMethodCall(me) : memberExpression.Expression;

               Type type = null;

               PropertyInfo prop = memberExpression.Member as PropertyInfo;

               if (prop != null)


                   type = prop.PropertyType;




                   FieldInfo field = memberExpression.Member as FieldInfo;

                   if (field != null)


                       type = field.FieldType;



               if (type == null)


                   throw new NotImplementedException();


               MethodInfo methodInfo = maybeMethod.MakeGenericMethod(new[] { memberExpression.Member.DeclaringType, type });

               ParameterExpression p = Expression.Parameter(memberExpression.Member.DeclaringType, “p”);

               LambdaExpression maybeLamba = Expression.Lambda(Expression.MakeMemberAccess(p, memberExpression.Member), new[] { p });

               return Expression.Call(null, methodInfo, new[] { ex, maybeLamba });



    Which can be used as:

               string testString = “Test”;

               int length4 = Null.Try(() => testString.Length); // 4

               string nullString = null;

               int length0 = Null.Try(() => nullString.Length); // 0

  2. AlexJ says:


    that is pretty cool. Nice work