Impossibile eseguire il cast dell'oggetto di tipo 'System.Linq.Expressions.UnaryExpression' per digitare 'System.Linq.Expressions.MemberExpression'

c# exception-handling expression-trees linq

Domanda

Ho creato un metodo in C # per ottenere methodname

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

e chiamandolo come

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

Funziona bene se la proprietà è stringa e per tutti gli altri tipi dà questa eccezione:

Impossibile eseguire il cast dell'oggetto di tipo 'System.Linq.Expressions.UnaryExpression' per digitare 'System.Linq.Expressions.MemberExpression'.

  1. Ho modificato la stringa in oggetto nella firma del metodo, ma poi ha fallito di nuovo.
  2. Ho cambiato la chiamata da x => x.PropertyName a x => Convert.ToString(x.PropertyName) e non riesce ancora

Dove mi sbaglio?

Risposta accettata

È necessaria una linea separata per estrarre il membro in cui l'espressione di input è un'espressione unaria.

Ho appena convertito questo da VB.Net, quindi potrebbe essere leggermente fuori - fammi sapere se ho bisogno di apportare qualche piccola modifica:

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

La versione 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

Si noti che l'espressione di input non restituisce necessariamente la stringa - che ti costringe a leggere solo le proprietà che restituiscono le stringhe.


Risposta popolare

Questo è apparentemente correlato al boxing / unboxing. Le espressioni Lambda che restituiscono tipi di valore che richiedono il pugilato verranno rappresentate come UnariaExpressioni mentre quelle che restituiscono i tipi di riferimento verranno rappresentate come MemberExpressions.



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché