I have a problem that has been nagging me for some time now and I can't find the answer.
I need to obtain the name of the property that is being referenced in a Lambda Expression. I would provide the lambda expression to a method that would return a string. For example if I have:
x => x.WeirdPropertyName
then the method would return:
"WeirdPropertyName"
I have read that it can be done with expression trees, but the answer has eluded me.
Thanks for any help
In C#, accessing a variable outside the scope of a function is possible and considered normal.
Lambda expressions in C# are used like anonymous functions, with the difference that in Lambda expressions you don't need to specify the type of the value that you input thus making it more flexible to use. The '=>' is the lambda operator which is used in all lambda expressions.
Lambda expressions are like anonymous methods but with much more flexibility. When using a lambda expression, you don't need to specify the type of the input. Hence, a lambda expression provides a shorter and cleaner way of representing anonymous methods.
A lambda expression with an expression on the right side of the => operator is called an expression lambda. An expression lambda returns the result of the expression and takes the following basic form: C# Copy. (input-parameters) => expression. The body of an expression lambda can consist of a method call.
Here you go:
string GetPropertyName<T>(Expression<Func<T>> property)
{
var propertyInfo = (property.Body as MemberExpression).Member as PropertyInfo;
if (propertyInfo == null)
{
throw new ArgumentException("The lambda expression 'property' should point to a valid Property");
}
return propertyInfo.Name;
}
I've got a pretty comprehensive answer here.
In addition to dealing with expressions like x => x.WeirdPropertyName
, it can also deal with "extended" expressions such as x => x.WeirdMember.WeirdPropertyName
.
Here's the code from that answer:
// code adjusted to prevent horizontal overflow
static string GetFullPropertyName<T, TProperty>
(Expression<Func<T, TProperty>> exp)
{
MemberExpression memberExp;
if (!TryFindMemberExpression(exp.Body, out memberExp))
return string.Empty;
var memberNames = new Stack<string>();
do
{
memberNames.Push(memberExp.Member.Name);
}
while (TryFindMemberExpression(memberExp.Expression, out memberExp));
return string.Join(".", memberNames.ToArray());
}
// code adjusted to prevent horizontal overflow
private static bool TryFindMemberExpression
(Expression exp, out MemberExpression memberExp)
{
memberExp = exp as MemberExpression;
if (memberExp != null)
{
// heyo! that was easy enough
return true;
}
// if the compiler created an automatic conversion,
// it'll look something like...
// obj => Convert(obj.Property) [e.g., int -> object]
// OR:
// obj => ConvertChecked(obj.Property) [e.g., int -> long]
// ...which are the cases checked in IsConversion
if (IsConversion(exp) && exp is UnaryExpression)
{
memberExp = ((UnaryExpression)exp).Operand as MemberExpression;
if (memberExp != null)
{
return true;
}
}
return false;
}
private static bool IsConversion(Expression exp)
{
return (
exp.NodeType == ExpressionType.Convert ||
exp.NodeType == ExpressionType.ConvertChecked
);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With