无法将类型为"System.Linq.Expressions.UnaryExpression"的对象强制转换为"System.Linq.Expressions.MemberExpression"

Nik*_*wal 34 c# linq exception-handling expression-trees

在C#中创建了一个方法来获取methodname

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

并称之为

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

如果property是string,并且所有其他类型都提供此异常,则此方法正常:

无法将类型为"System.Linq.Expressions.UnaryExpression"的对象强制转换为"System.Linq.Expressions.MemberExpression".

  1. 我在方法签名中将字符串更改为对象,但随后又失败了.
  2. 我改变从打电话x => x.PropertyNamex => Convert.ToString(x.PropertyName),它仍然失败

我哪里错了?

Jon*_*ton 55

您需要一个单独的行来提取输入表达式为一元表达式的Member.

刚刚从VB.Net转换了这个,所以可能稍微关闭 - 让我知道我是否需要进行任何小调整:

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;
    }                
}
Run Code Online (Sandbox Code Playgroud)

VB版本是:

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
Run Code Online (Sandbox Code Playgroud)

请注意,输入表达式不会返回字符串 - 这会限制您只读取返回字符串的属性.

  • 人们想知道为什么这样的东西还没有被包含在BCL或扩展中.这非常有用. (4认同)

Sco*_*nro 9

显然与装箱/拆箱有关.返回需要装箱的值类型的Lambda表达式将表示为UnaryExpressions,而返回引用类型的表达式将表示为MemberExpressions.

  • 这详细说明了评分最高的答案,并为那些对答案不满意的人提供了进一步的见解。 (3认同)