Linq Func / Expression Local Evaluation - PullRequest
       4

Linq Func / Expression Local Evaluation

1 голос
/ 06 августа 2010

Учитывая этот код:

        int min = 0;

        Expression<Func<List<IUser>, bool>> ulContainsJohn = 
                    (l => l.Where(u => u.FirstName == "John").Count() > min);

        Assert.AreEqual(true, ulContainsJohn.Compile()(userList));

        min = 3;

        Assert.AreEqual(true, ulContainsJohn.Compile()(userList));

В списке содержится 1 «Джон», но второе утверждение не выполняется. Как мне связать значение min с функцией Func, чтобы он не пытался переоценить переменную min?

Разъяснение: я не хочу менять подпись. Я хочу, чтобы дерево выражений оценивало min не как переменную, а как константное выражение. Есть ли способ преобразовать оценку min, чтобы дерево имело постоянное выражение вместо оценки переменной?

Ответы [ 3 ]

1 голос
/ 06 августа 2010

Вы должны сделать это параметром.

    Expression<Func<List<IUser>, int,  bool>> ulContainsJohn = 
                (List<IUser> l, int min) =>  (l.Where(u => u.FirstName == "John").Count() > min);


    ulContainsJohn.Compile()(userList, min);
1 голос
/ 06 августа 2010

Редактировать: прочитайте свой комментарий, попробуйте создать функцию.

Func<int, Func<List<IUser>, bool>> createFn = (min) =>
    (l) => (l.Count(u => u.FirstName == "John") > min);

Func<List<IUser>, bool>> contains0 = createFn(0);

Assert.AreEqual(true, contains0(userList));

Func<List<IUser>, bool>> contains3 = createFn(3);

Assert.AreEqual(true, contains3(userList));

Попробуйте использовать массив из 1 элемента.Ужасно, но это работает.

var values = new int[] { 0 };

Expression<Func<List<IUser>, bool>> ulContainsJohn = 
                (l => l.Where(u => u.FirstName == "John").Count() > values[0]);

Assert.AreEqual(true, ulContainsJohn.Compile()(userList));

values[0] = 3;

Assert.AreEqual(true, ulContainsJohn.Compile()(userList));

Другой вариант, лучше:

private int Minimum { get; set; }

...

Expression<Func<List<IUser>, bool>> ulContainsJohn = 
            (l => l.Where(u => u.FirstName == "John").Count() > Minimum);

Func<List<IUser>, bool> fn = ulContainsJohn.Compile();
Assert.AreEqual(true, fn(userList));

Minimum = 3;

Assert.AreEqual(true, fn(userList));
0 голосов
/ 06 августа 2010

Самое простое решение - создать отдельную переменную:

    int min = 0;
    int staticMin = min;
    Func<List<IUser>, bool> ulContainsJohn = 
                l => l.Where(u => u.FirstName == "John").Count() > staticMin ;
...