Utilisation de l'expression lambda pour obtenir la propriété OU le nom de type

c# expression-trees lambda

Question

Comment puis-je adapter la méthode ci-dessous pour que fonctionner lorsque l'expression lambda fait référence à l'instance elle-même?

par exemple au lieu de

x => x.Name

l'expression est

x => x

donc si j'avais une classe "Car", je pourrais renvoyer la chaîne "Car" au lieu de pouvoir uniquement utiliser ses propriétés (par exemple, Car.Colour)

La méthode:

public static string GetMemberName(Expression expression)
    {
        if (expression is LambdaExpression)
            expression = ((LambdaExpression)expression).Body;

        if (expression is MemberExpression)
        {
            var memberExpression = (MemberExpression)expression;
            if (memberExpression.Expression.NodeType ==
                ExpressionType.MemberAccess)
            {
                return GetMemberName(memberExpression.Expression)
                       + "."
                       + memberExpression.Member.Name;
            }
            return memberExpression.Member.Name;
        }


        if (expression is UnaryExpression)
        {
            var unaryExpression = (UnaryExpression)expression;

            if (unaryExpression.NodeType != ExpressionType.Convert)
                throw new Exception(string.Format(
                    "Cannot interpret member from {0}",
                    expression));
            return GetMemberName(unaryExpression.Operand);
        }
        throw new Exception(string.Format(
            "Could not determine member from {0}",
            expression));
    }

c'est-à-dire que je veux quelque chose comme:

if (expression is SomeExpressionThatReturnsAnInstance)
{
    return (name of type of instance);
}

Réponse acceptée

J'ai remonté à la construction de l'expression. Il ne contient vraiment aucune information d'instance et aucun moyen d'obtenir le nom du type.

static Expression<Func<object, object>> thisObject = x => x;

Il est donc impossible qu'un nom de type puisse être dérivé d'une expression qui n'a même pas de type (autre qu'un objet).

La méthode utilisée pour générer une expression qui renvoie un nom de propriété:

LambdaExpression BuildExpression(Type rootType, string propertyName)
    {
        try
        {
            var properties = propertyName.Split('.');
            ParameterExpression arg = Expression.Parameter(rootType, "x");
            Expression expr = arg;
            foreach (string property in properties)
            {
                PropertyInfo propertyInfo = rootType.GetProperty(property);
                if (propertyInfo == null)
                    return null;
                expr = Expression.Property(expr, propertyInfo);
                rootType = propertyInfo.PropertyType;
            }
            return Expression.Lambda(expr, arg);
        }
        catch (System.Exception ex)
        {
            return null;
        }
    }

Réponse populaire

Je peux être mal compris, mais un x => x direct x => x sera un ParameterExpression . Ajoutez simplement un test supplémentaire sous votre test is MemberExpression existant:

if (expression is MemberExpression)
{
    // As-is
}
// New condition
if (expression is ParameterExpression)
{
    return expression.Type.Name;
}

En utilisant ce code:

class Car { public string Color { get; set; }}

Expression<Func<Car, string>> expr1 = x => x.Color;
Expression<Func<Car, Car>> expr2 = x => x;

Console.WriteLine(GetMemberName(expr1));
> Color
Console.WriteLine(GetMemberName(expr2));
> Car


Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi