Cannot pass an object of type "System.Linq.Expressions.UnaryExpression" to enter "System.Linq.Expressions.MemberExpression"

I created a method in C # to get the method name

public string GetCorrectPropertyName<T>(Expression<Func<T, string>> expression) { return ((MemberExpression)expression.Body).Member.Name; // Failure Point } 

and calling him

 string lcl_name = false; public string Name { get { return lcl_name ; } set { lcl_name = value; OnPropertyChanged(GetCorrectPropertyName<ThisClassName>(x => x.Name)); } } 

This works fine if the property is a string, and for all other types this is an exception:

Cannot pass an object of type "System.Linq.Expressions.UnaryExpression" to enter "System.Linq.Expressions.MemberExpression".

  • I changed the string to an object in the method signature, but then it worked again.
  • I changed the call from x => x.PropertyName to x => Convert.ToString(x.PropertyName) and it still doesn't work

Where am I mistaken?

+29
c # exception-handling linq expression-trees
Sep 14 '12 at 8:09
source share
3 answers

You need a separate line to retrieve a member, where the input expression is a Unary expression.

Just changed it from VB.Net, so it can be a little disconnected - let me know if I need to make any minor changes:

 public string GetCorrectPropertyName<T>(Expression<Func<T, Object>> expression) { if (expression.Body is MemberExpression) { return ((MemberExpression)expression.Body).Member.Name; } else { var op = ((UnaryExpression)expression.Body).Operand; return ((MemberExpression)op).Member.Name; } } 

VB Version:

 Public Shared Function GetCorrectPropertyName(Of T) _ (ByVal expression As Expression(Of Func(Of T, Object))) As String If TypeOf expression.Body Is MemberExpression Then Return DirectCast(expression.Body, MemberExpression).Member.Name Else Dim op = (CType(expression.Body, UnaryExpression).Operand) Return DirectCast(op, MemberExpression).Member.Name End If End Function 

Note that the input expression does not necessarily return a string - this limits only the reading of properties that return strings.

+44
Sep 14 '12 at 8:19
source share
β€” -

This is obviously related to boxing / unboxing. Lambda expressions that return value types that require boxing will be represented as UnaryExpressions, while those that return reference types will be represented as MemberExpressions.

+5
Nov 28 '14 at 7:58
source share

After I asked this question (yes, I am OP), I received comments on the question from Jon

and I came up with this

 public string ResolvePropertyName<TEntity>(Expression<Func<TEntity>> expression) { try { if (expression == null) { Throw New ArgumentNullException("propertyExpression") } object memberExpression = expression.Body as MemberExpression; if (memberExpression == null) { Throw New ArgumentException("The expression is not a member access expression.", "propertyExpression") } object property = memberExpression.Member as PropertyInfo; if (property == null) { Throw New ArgumentException("The member access expression does not access a property.", "propertyExpression") } object getMethod = property.GetGetMethod(true); if (getMethod.IsStatic) { Throw New ArgumentException("The referenced property is a static property.", "propertyExpression") } return memberExpression.Member.Name; } catch (Exception ex) { return string.Empty; } } 
+4
Sep 14 '12 at 11:05
source share



All Articles