Question

L'objectif est d'obtenir un tableau de MemberExpressions de deux LambdaExpressions. La première est convertible en un MethodCallExpression qui renvoie l'instance d'un objet (Expression<Func<T>>). La seconde expression Lambda prendrait le résultat de la première expression et de retourner un élément imbriqué compilé (Expression<Func<T,TMember>>). On peut supposer que la deuxième expression Lambda ne fera appel à des propriétés imbriquées, mais peut faire plusieurs de ces appels.

Ainsi, la signature de la méthode que je suis en train de créer est:

MemberExpression[] GetMemberExpressionArray<T,TValue>(Expression<Func<T>> instanceExpression, Expression<Func<T,TValue>> nestedMemberExpression)

nestedMemberExpression sera supposé prendre un argument de la forme

parent => parent.ChildProperty.GrandChildProperty

et la matrice résultante représente la MemberAccess de parent à ChildProperty et de la valeur de ChildProperty à GrandChildProperty.

Je l'ai déjà retourné la dernière MemberExpression en utilisant la méthode d'extension suivante.

public static MemberExpression GetMemberExpression<T, TValue>(Expression<Func<T, TValue>> expression)
{
    if (expression == null)
    {
        return null;
    }
    if (expression.Body is MemberExpression)
    {
        return (MemberExpression)expression.Body;
    }
    if (expression.Body is UnaryExpression)
    {
        var operand = ((UnaryExpression)expression.Body).Operand;
        if (operand is MemberExpression)
        {
            return (MemberExpression)operand;
        }
        if (operand is MethodCallExpression)
        {
            return ((MethodCallExpression)operand).Object as MemberExpression;
        }
    }
    return null;
} 

Maintenant, je sais qu'il ya plusieurs façons d'y parvenir. Le plus immédiatement intuitive me serait de boucle à travers la propriété .Expression pour obtenir des références les premiers d'expression et de capture à chaque MemberExpression le long du chemin. Cela peut être la meilleure façon de le faire, mais il ne peut pas. Je ne connais pas extraordinaire avec les coûts de performance que je reçois d'utiliser des expressions comme celle-ci. Je sais un MemberExpression a une MemberInfo et que la réflexion est censé mal la performance.

J'ai essayé de rechercher des informations sur les expressions, mais mes ressources ont été très limitées dans ce que j'ai trouvé.

J'apprécierait des conseils sur la façon d'accomplir cette tâche (et ce type de tâche, en général) avec des performances et une fiabilité optimale.

Était-ce utile?

La solution

Je ne sais pas pourquoi cela a été taguée performances , mais plus facile comme je peux penser à extraire membres-expressions d'un arbre est à la sous-classe ExpressionVisitor . Cela devrait être beaucoup plus simple que d'écrire manuellement la logique de « développer » les différents types d'expressions et de parcourir l'arborescence.

Vous devrez probablement remplacer le VisitMember procédé de telle sorte que:

  1. est capturé chaque expression des membres.
  2. Ses enfants sont visités.

J'imagine que ressemblerait à quelque chose comme:

protected override Expression VisitMember(MemberExpression node)
{
    _myListOfMemberExpressions.Add(node);
    return base.VisitMember(node);
}

Je suis un peu clair sur le reste de votre tâche; il semble que vous voulez Ressaisissez paramètres-expressions, dans ce cas, vous voudrez peut-être regarder cette réponse de Marc Gravell.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top