Подтвердить что ты не робот

Как проверить, являются ли два выражения <Func <T, bool >> одинаковыми

Можно ли узнать, совпадают ли два выражения?

Как и следующие четыре выражения:

        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;

Тогда, по крайней мере, мы можем видеть, что:

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

Но могу ли я сделать что-нибудь, чтобы узнать это в моем коде?

Заглянул в библиотеку msdn, где говорится, что

Equals: Определяет, соответствует ли указанный объект текущему Object. (Унаследовано от Object.)

который, как я полагаю, означает, что по крайней мере класс Expression не переопределил метод equals, чтобы стать Equableable? Итак, как бы вы это сделали? Или я слишком много спрашиваю?: Р

4b9b3361

Ответ 1

Вы можете посмотреть тип ExpressionEqualityComparer, который используется внутри Linq to db4o. Он реализует интерфейс IEqualityComparer <T> , поэтому он может использоваться для общих коллекций, а также для автономного использования.

Он использует тип ExpressionComparison для сравнения двух выражений для равенства и HashCodeCalculation, чтобы вычислить хэш-код из выражения.

Все это связано с посещением дерева выражений, поэтому может быть довольно дорогостоящим, если вы делаете это повторно, но оно также может быть весьма удобным.

Код доступен в GPL или dOCL

Например, здесь ваш тест:

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

И он действительно печатает True, False, False.

Ответ 2

Как ленивый ответ, вы можете проверить ToString() - он должен хотя бы указать, где они явно отличаются (хотя он будет включать в себя имя-var там, так что это должно быть одинаково).

Для точной проверки эквивалентности... гораздо сложнее - много работы, по множеству разных типов node.

Ответ 3

Мне кажется, что это может быть трудно сделать, за исключением самых простых случаев.

Например:

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;

Технически, они равны, но как его можно определить без оценки IEnuemrable, возвращаемого в каждом выражении?