Évaluation locale de Linq Func / Expression

expression-trees linq

Question

Étant donné ce code:

        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 liste contient 1 "John", mais la deuxième assertion échoue. Comment lier la valeur de min au Func avec impatience, de sorte qu'il n'essaye pas de réévaluer la variable min?

Précision: je ne veux pas changer la signature. Je veux que l'arbre d'expression avalate min non pas comme une variable, mais comme une expression constante. Est-il possible de convertir l'évaluation de min pour que l'arbre ait une expression constante au lieu d'une évaluation de variable?

Réponse acceptée

Edit: lisez votre commentaire, essayez un créateur de fonction.

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

Essayez d'utiliser un tableau à 1 élément. Moche, mais ça marche.

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

Une autre option, mieux:

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

Réponse populaire

Vous devrez en faire un paramètre.

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


    ulContainsJohn.Compile()(userList, min);



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi