Linq Func / Expresión Evaluación Local

expression-trees linq

Pregunta

Dado este código:

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

La lista contiene 1 "John", pero la segunda afirmación falla. ¿Cómo puedo vincular el valor de min con la función con entusiasmo, para que no intente volver a evaluar la variable min?

Aclaración: No quiero cambiar la firma. Quiero que el árbol de expresiones valore mín no como una variable, sino como una expresión constante. ¿Hay alguna forma de convertir la evaluación de min para que el árbol tenga una expresión constante en lugar de una evaluación de variable?

Respuesta aceptada

Editar: lee tu comentario, prueba un creador de funciones.

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

Trate de usar una matriz de 1 elemento. Feo, pero funciona.

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

Otra opción, mejor:

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

Respuesta popular

Tendrías que convertirlo en un parámetro.

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


    ulContainsJohn.Compile()(userList, min);


Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow