Abrufen des Eigenschaftsnamens aus dem Lambda-Ausdruck

c# expression-trees lambda linq

Frage

Gibt es eine bessere Möglichkeit, den Eigenschaftsnamen zu erhalten, wenn er über einen Lambda-Ausdruck übergeben wird? Hier ist, was ich derzeit habe.

z.B.

GetSortingInfo<User>(u => u.UserId);

Es funktionierte, indem es als eine Memberexpression nur dann geworfen wurde, wenn die Eigenschaft eine Zeichenfolge war. Da nicht alle Eigenschaften Strings sind, musste ich ein Objekt verwenden, aber dann würde es einen unären Ausdruck für diese zurückgeben.

public static RouteValueDictionary GetInfo<T>(this HtmlHelper html, 
    Expression<Func<T, object>> action) where T : class
{
    var expression = GetMemberInfo(action);
    string name = expression.Member.Name;

    return GetInfo(html, name);
}

private static MemberExpression GetMemberInfo(Expression method)
{
    LambdaExpression lambda = method as LambdaExpression;
    if (lambda == null)
        throw new ArgumentNullException("method");

    MemberExpression memberExpr = null;

    if (lambda.Body.NodeType == ExpressionType.Convert)
    {
        memberExpr = 
            ((UnaryExpression)lambda.Body).Operand as MemberExpression;
    }
    else if (lambda.Body.NodeType == ExpressionType.MemberAccess)
    {
        memberExpr = lambda.Body as MemberExpression;
    }

    if (memberExpr == null)
        throw new ArgumentException("method");

    return memberExpr;
}

Akzeptierte Antwort

Ich fand eine andere Möglichkeit, wie Sie es tun können, die Quelle und Eigenschaft stark typisiert zu haben und explizit die Eingabe für das Lambda abzuleiten. Nicht sicher, ob das die richtige Terminologie ist, aber hier ist das Ergebnis.

public static RouteValueDictionary GetInfo<T,P>(this HtmlHelper html, Expression<Func<T, P>> action) where T : class
{
    var expression = (MemberExpression)action.Body;
    string name = expression.Member.Name;

    return GetInfo(html, name);
}

Und dann nenn es so.

GetInfo((User u) => u.UserId);

und voila es funktioniert.
Danke allen.


Expertenantwort

Nun, es ist nicht notwendig, .Name.ToString() zu nennen, aber im Großen und Ganzen geht es darum, ja. Die einzige Überlegung, die Sie möglicherweise benötigen, ist, ob x.Foo.Bar "Foo", "Bar" oder eine Ausnahme zurückgeben soll - dh müssen Sie überhaupt iterieren.

(re comment) für mehr über flexible Sortierung, siehe hier .



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum