Verwenden des Lambda-Ausdrucks zum Abrufen der Eigenschaft oder des Typnamens

c# expression-trees lambda

Frage

Wie kann ich die unten beschriebene Methode anpassen, wenn der Lambda-Ausdruck auf die tatsächliche Instanz selbst verweist?

zB statt

x => x.Name

der Ausdruck ist

x => x

Wenn ich also eine Klasse "Car" hätte, könnte ich die Zeichenfolge "Car" zurückgeben, anstatt nur auf ihren Eigenschaften zu arbeiten (zB Car.Colour)

Die Methode:

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

dh ich möchte etwas wie:

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

Akzeptierte Antwort

Ich habe das auf die Konstruktion des Ausdrucks zurückverfolgt. Es enthält keine Instanzinformationen und keine Möglichkeit, den Typnamen abzurufen.

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

Es gibt also keine Möglichkeit, dass ein Typname von einem Ausdruck abgeleitet werden kann, der nicht einmal einen Typ hat (außer Objekt).

Die Methode, die zum Generieren eines Ausdrucks verwendet wird, der einen Eigenschaftsnamen zurückgibt:

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

Beliebte Antwort

Ich mag ein Missverständnis sein, aber ein direktes x => x wird eine ParameterExpression . is MemberExpression einfach einen zusätzlichen Test unter dem vorhandenen is MemberExpression Test hinzu:

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

Mit diesem 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


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