Impossible de lancer objet du système de type'.Linq.Expression.UnaryExpression' de type 'System.Linq.Expression.MemberExpression"
j'ai créé une méthode dans C# pour obtenir le nom de la méthode
public string GetCorrectPropertyName<T>(Expression<Func<T, string>> expression)
{
return ((MemberExpression)expression.Body).Member.Name; // Failure Point
}
et l'appelant
string lcl_name = false;
public string Name
{
get { return lcl_name ; }
set
{
lcl_name = value;
OnPropertyChanged(GetCorrectPropertyName<ThisClassName>(x => x.Name));
}
}
cela fonctionne très bien si la propriété est chaîne et pour tous les autres types donne cette exception:
impossible de lancer objet du système de type.Linq.Expression.UnaryExpression' de type 'System.Linq.Expression.MemberExpression".
- I changé de chaîne pour objet de signature de la méthode, mais alors il échoue à nouveau.
- j'ai changé l'appel de
x => x.PropertyName
àx => Convert.ToString(x.PropertyName)
et il échoue toujours
Où ai-je tort?
3 réponses
vous avez besoin d'une ligne séparée pour extraire le membre où l'expression d'entrée est une Expression unaire.
vient de convertir CE de VB.Net, donc pourrait être légèrement off-me faire savoir si j'ai besoin de faire des modifications mineures:
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 version VB est:
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
notez que l'expression input ne renvoie pas nécessairement string - ce qui vous contraint à ne lire que les propriétés qui renvoient des chaînes.
c'est apparemment lié à la boxe/unboxing. Les expressions Lambda retournant des types de valeur qui nécessitent de la boxe seront représentées comme des expressions simples tandis que celles qui renvoient des types de référence seront représentées comme des expressions MemberExpressions.
après avoir posé cette question(oui je suis OP) j'ai reçu des commentaires sur la question de Jon
et j'ai trouvé ce
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;
}
}