Cómo comprobar si dos expresiones <Func > son las mismas

¿Es posible descubrir si dos expresiones son iguales?

Como dado las siguientes cuatro expresiones:

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

Entonces, al menos podemos ver eso:

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

¿Pero puedo hacer algo para descubrir esto en mi código?

Echó un vistazo en la biblioteca msdn, donde dice que

Equals : determina si el Objeto especificado es igual al Object actual. (Heredado de Object )

lo que supongo significa que al menos la clase Expresión no ha anulado el método igual para convertirse en Equatable? Entonces, ¿cómo harías esto? ¿O estoy pidiendo demasiado aquí? :pag

    Puede echar un vistazo al tipo ExpressionEqualityComparer que se utiliza dentro de Linq a db4o . Implementa la interfaz IEqualityComparer , por lo que es útil para colecciones genéricas, así como para un uso independiente.

    Utiliza el tipo ExpressionComparison para comparar dos expresiones para igualdad y HashCodeCalculation para calcular un código hash a partir de una expresión.

    Todo implica visitar el árbol de expresiones, por lo que puede ser bastante costoso si lo haces de forma repetida, pero también puede ser bastante útil.

    El código está disponible bajo la GPL o el dOCL

    Por ejemplo, esta es tu prueba:

     using System; using System.Linq.Expressions; using Db4objects.Db4o.Linq.Expressions; class Test { static void Main () { Expression> a = x => false; Expression> b = x => false; Expression> c = x => true; Expression> d = x => x == 5; Func eq = ExpressionEqualityComparer.Instance.Equals; Console.WriteLine (eq (a, b)); Console.WriteLine (eq (a, c)); Console.WriteLine (eq (a, d)); } } 

    Y de hecho imprime Verdadero, Falso, Falso.

    Como respuesta floja, puede verificar ToString() : al menos debería indicar dónde son claramente diferentes (aunque incluirá el var-name allí, por lo que debería ser el mismo).

    Para verificar la equivalencia con precisión … mucho más difícil: mucho trabajo, en muchos tipos diferentes de nodos.

    Me sorprende que esto sea difícil de hacer, excepto en el caso más simple.

    Por ejemplo:

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

    Técnicamente, estos son iguales, pero ¿cómo podría determinarse sin evaluar el IEnuemrable devuelto en cada expresión?