Question

    

Cette question a déjà une réponse ici:

         

Est-il possible de savoir si deux expressions sont les mêmes?

Comme donné les quatre expressions suivantes:

        Expression<Func<int, bool>> a = x => false;
        Expression<Func<int, bool>> b = x => false;
        Expression<Func<int, bool>> c = x => true;
        Expression<Func<int, bool>> d = x => x == 5;

Alors, au moins nous peut voir que:

  • a == b
  • a != c
  • a != d

Mais je peux faire quelque chose pour trouver cela dans mon code?

A pris un coup d'oeil dans la bibliothèque msdn, où il est dit que

  

Equals: détermine si l'objet spécifié est égal à la Object actuelle. (Hérité de <=>).

que je suppose que signifie qu'au moins la classe d'expression n'a pas overrided la méthode equals pour devenir assimilables? Alors, comment voulez-vous faire? Ou suis-je trop demander ici? : P

Était-ce utile?

La solution

Vous pouvez jeter un oeil à type ExpressionEqualityComparer qui est utilisé à l'intérieur Linq à db4o . Il implémente l'interface IEqualityComparer , il est donc utilisable pour les collections génériques, ainsi que pour une utilisation autonome.

Il utilise le type ExpressionComparison pour comparer deux expressions pour l'égalité, et HashCodeCalculation , pour calculer un code de hachage à partir d'une expression.

Tout consiste à visiter l'arbre d'expression, il peut donc être assez coûteux si vous le faites à plusieurs reprises, mais il peut aussi être très pratique.

Le code est disponible sous la licence GPL ou le dOCL

Par exemple, voici votre test:

using System;
using System.Linq.Expressions;

using Db4objects.Db4o.Linq.Expressions;

class Test {

    static void Main ()
    {
        Expression<Func<int, bool>> a = x => false;
        Expression<Func<int, bool>> b = x => false;
        Expression<Func<int, bool>> c = x => true;
        Expression<Func<int, bool>> d = x => x == 5;

        Func<Expression, Expression, bool> eq =
            ExpressionEqualityComparer.Instance.Equals;

        Console.WriteLine (eq (a, b));
        Console.WriteLine (eq (a, c));
        Console.WriteLine (eq (a, d));
    }
}

Et il imprime en effet True, False, False.

Autres conseils

En réponse paresseux, vous pouvez vérifier ToString() -. Il devrait au moins indiquer où ils sont clairement différents (bien qu'il comprendra le var nom là-bas, de sorte que faudrait être le même)

Pour vérifier l'équivalence avec précision ... beaucoup plus difficile -. Beaucoup de travail, sur un grand nombre de différents types de nœuds

Il me semble que cela pourrait être difficile à faire, sauf dans le plus simple des cas.

Par exemple:

var numbers1 = Enumerable.Range(1, 20);
Expression<Func<int, IEnumerable<int>>> a = x => numbers1;
var numbers2 = Enumerable.Range(1, 20);
Expression<Func<int, IEnumerable<int>>> b = x => numbers2;

Techniquement, ils sont égaux, mais comment pourrait-il être déterminé sans évaluer le IEnuemrable retourné dans chaque expression?

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