Das Objekt des Typs 'System.Linq.Expressions.UnaryExpression' konnte nicht in den Typ 'System.Linq.Expressions.MemberExpression' umgewandelt werden.

c# exception-handling expression-trees linq

Frage

Ich habe eine Methode in C # erstellt , um den Methodennamen zu erhalten

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

und nennen es als

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

Dies funktioniert einwandfrei, wenn die Eigenschaft Zeichenfolge ist und für alle anderen Typen diese Ausnahme gilt:

Das Objekt des Typs 'System.Linq.Expressions.UnaryExpression' kann nicht in den Typ 'System.Linq.Expressions.MemberExpression' umgewandelt werden.

  1. Ich habe in der Methodensignatur die Zeichenfolge in Objekt geändert, aber dann schlägt sie erneut fehl.
  2. Ich änderte den Aufruf von x => x.PropertyName in x => Convert.ToString(x.PropertyName) und schlägt immer noch fehl

Wo liege ich falsch?

Akzeptierte Antwort

Sie benötigen eine separate Zeile, um das Member zu extrahieren, dessen Eingabeausdruck ein unärer Ausdruck ist.

Ich habe das nur von VB.Net konvertiert, also könnte es etwas anders sein - lassen Sie mich wissen, wenn ich kleinere Änderungen vornehmen muss:

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;
    }                
}

Die VB-Version ist:

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

Beachten Sie, dass der Eingabeausdruck die Zeichenfolge nicht unbedingt zurückgibt - dies beschränkt Sie darauf, nur Eigenschaften zu lesen, die Zeichenfolgen zurückgeben.


Beliebte Antwort

Dies hängt offenbar mit Boxen / Unboxing zusammen. Lambda-Ausdrücke, die Werttypen zurückgeben, die Boxing erfordern, werden als UnaryExpressions dargestellt, wohingegen diejenigen, die Referenztypen zurückgeben, als MemberExpressions dargestellt werden.



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow