Come verificare se due espressioni <Func > sono le stesse

È ansible scoprire se due espressioni sono uguali?

Come dato le seguenti quattro espressioni:

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

Quindi, almeno possiamo vedere che:

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

Ma posso fare qualcosa per scoprirlo nel mio codice?

Ho preso una sbirciatina nella libreria msdn, dove dice questo

    Equals : determina se l’object specificato è uguale Object corrente. (Ereditato da Object ).

    quale suppongo significhi che almeno la class di Espressione non ha scavalcato il metodo equals per diventare Equitable? Quindi come lo faresti? O sto chiedendo troppo qui? : p

    Puoi dare un’occhiata al tipo ExpressionEqualityComparer che è usato all’interno di Linq per db4o . Implementa l’interfaccia IEqualityComparer , quindi è utilizzabile per le raccolte generiche, nonché per un utilizzo standalone.

    Utilizza il tipo ExpressionComparison per confrontare due espressioni per l’uguaglianza e HashCodeCalculation per calcolare un hashcode da un’espressione.

    Tutto ciò comporta visitare l’albero delle espressioni, quindi può essere piuttosto costoso se lo si fa ripetutamente, ma può anche essere abbastanza utile.

    Il codice è disponibile sotto GPL o DOCL

    Ad esempio, ecco il tuo test:

     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)); } } 

    Ed effettivamente stampa True, False, False.

    Come risposta lazy, puoi controllare ToString() – dovrebbe almeno indicare dove sono chiaramente differenti (anche se includerà il var-name lì, quindi dovrebbe essere lo stesso).

    Per controllare con precisione l’equivalenza … molto più difficile: molto lavoro, su molti tipi di nodes diversi.

    Mi sembra che questo potrebbe essere difficile da fare, tranne nei casi più semplici.

    Per esempio:

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

    Tecnicamente, questi sono uguali, ma come potrebbe essere determinato senza valutare IEnuemrable restituito in ogni espressione?