I'm trying to write an extension-method to retrieve a property-path from a given LambdaExpression
.
I want to be able to call it like
var path = ((Event e) => e.Address.City.Name).ToChainedPath();
which would return Address.City.Name
as string
separated by .
.
Currently my extension looks like this
public static string ToChainedPath<TSource, TProperty>(this Expression<Func<TSource, TProperty>> expr, char separator = '.')
{
MemberExpression me;
switch (expr.Body.NodeType)
{
case ExpressionType.Convert:
case ExpressionType.ConvertChecked:
var ue = expr.Body as UnaryExpression;
me = ue?.Operand as MemberExpression;
break;
default:
me = expr.Body as MemberExpression;
break;
}
var propertyNames = new List<string>();
while (me != null)
{
propertyNames.Add(me.Member.Name);
me = me.Expression as MemberExpression;
}
propertyNames.Reverse();
return string.Join(separator, propertyNames);
}
Which is working fine when used like
Expression<Func<Event, string>> expression = e => e.Address.City.Name;
var propertyChain = expression.ToChainedPath();
But this does not work for what I want because (Event e) => e.Address.City.Name
is Func<Event, string>
and not Expression<Func<Event,string>>
.
I already tried to convert the Func
to an Expression
but nothing helped so far.
I also changed the extension to extend Func
instead of Expression
but then I loose the Body
.
Is this even possible to do?