Is there a better way to get the Property name when passed in via a lambda expression? Here is what i currently have.
eg.
GetSortingInfo<User>(u => u.UserId);
It worked by casting it as a memberexpression only when the property was a string. because not all properties are strings i had to use object but then it would return a unaryexpression for those.
public static RouteValueDictionary GetInfo<T>(this HtmlHelper html,
Expression<Func<T, object>> action) where T : class
{
var expression = GetMemberInfo(action);
string name = expression.Member.Name;
return GetInfo(html, name);
}
private static MemberExpression GetMemberInfo(Expression method)
{
LambdaExpression lambda = method as LambdaExpression;
if (lambda == null)
throw new ArgumentNullException("method");
MemberExpression memberExpr = null;
if (lambda.Body.NodeType == ExpressionType.Convert)
{
memberExpr =
((UnaryExpression)lambda.Body).Operand as MemberExpression;
}
else if (lambda.Body.NodeType == ExpressionType.MemberAccess)
{
memberExpr = lambda.Body as MemberExpression;
}
if (memberExpr == null)
throw new ArgumentException("method");
return memberExpr;
}
Starting with .NET 4.0 you can use
ExpressionVisitor
to find properties:Here is how you use this visitor:
now in C# 6 you can simply use nameof like this
nameof(User.UserId)
which has many benefits, among them is that this is done at compile time, not runtime.
https://msdn.microsoft.com/en-us/magazine/dn802602.aspx
I was playing around with the same thing and worked this up. It's not fully tested but seems to handle the issue with value types (the unaryexpression issue you ran into)
This is another answer:
Here's an update to method proposed by Cameron. The first parameter is not required.
You can do the following:
Extension methods:
You can:
I recently did a very similar thing to make a type safe OnPropertyChanged method.
Here's a method that'll return the PropertyInfo object for the expression. It throws an exception if the expression is not a property.
The
source
parameter is used so the compiler can do type inference on the method call. You can do the following