Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maybe monad using expression trees?

Ugly:

string city = null;
if (myOrder != null && myOrder.Customer != null)
  city = myOrder.Customer.City;

Better (maybe monad):

var city = myOrder
               .With(x => x.Customer)
               .With(x => x.City)

Even better? Any reason this couldn't be written?

var city = Maybe(() => myOrder.Customer.City);
like image 401
Brian Low Avatar asked Dec 09 '10 21:12

Brian Low


1 Answers

Yes, it should be possible. However, it's quite a bit more complicated than it looks on the surface to implement an expression tree re-writer correctly. Especially if you want to be able to correctly handle fields, properties, indexed properties, method calls, and other constructs that are valid in arbitrary expressions.

It may also not be the most well-performing operation since to evaluate the expression you have to dynamically compile the expression tree into a lambda function each time.

There's an implementation on this pattern on CodePlex. I've never personally used it, so I can't say how well implemented it is, or whether it handles all of the cases I've described.

An alternative to creating an expression tree re-writer, is to write Maybe() to accept a lambda function (rather than an expression tree) and catch any ArgumentNullException thrown, returning default(T) in those cases. It rubs many people the wrong way to use exceptions for flow control in this way ... but it's certainly an easier implementation to get right. I personally avoid it myself since it can mask null reference errors within methods called as part of the expression, which is not desirable.

like image 115
LBushkin Avatar answered Sep 29 '22 10:09

LBushkin