Let's assume that I have these dummy classes defined:
public class MyObject
{
public InterestingFact InterestingFact { get; set; }
}
public class InterestingFact
{
public Detail Detail { get; set; }
}
public class Detail
{
public string Information { get; set; }
}
I also have an instance of MyObject
:
var obj = new MyObject() { InterestingFact = new InterestingFact() };
If I want to try to access the Information
property, I could do something like this:
string info = null;
if (obj != null
&& obj.InterestingFact != null
&& obj.InterestingFact.Detail != null)
{
info = obj.InterestingFact.Detail.Information;
}
Ignoring, for the sake of this discussion, the Law of Demeter, this is not a whole lot of fun every time I want to access something deep within an object I have. I can, of course, create an extension method:
public static U NullOr<T, U>(this T target, Func<T, U> selector)
{
if (EqualityComparer<T>.Default.Equals(target, default(T)))
{
return default(U);
}
return selector(target);
}
This makes selecting the data a little easier:
// Here I have a null of type string.
var info = obj.NullOr(o => o.InterestingFact).NullOr(f => f.Detail).NullOr(d => d.Information);
However, this is still a little long winded. Ideally, I'd like to do something more like this:
// Here I should still have a null of type string.
var info = obj.NullOr(o => o.InterestingFact.Detail.Information);
I've never worked with Expression
s; if I take in an Expression<Func<T, U>>
instead of the Func<T, U>
in NullOr
, it looks to me like it is one member access rather than three. Is there a way to approach the above, or is this formulation out of reach?
(There's also, of course, the concern with the last fomulation that the expression sent in could be something other than just chained member access..)