Comment vérifier si deux Expression > sont les mêmes [double]
-
21-08-2019 - |
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 à laObject
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
La solution
Vous pouvez jeter un oeil à type ExpressionEqualityComparer qui est utilisé à l'intérieur Linq à db4o . Il implémente l'interface IEqualityComparer
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?