Given this 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));
The list contains 1 "John", yet the second assert fails. How do I bind the value of min to the Func eagerly, so it doesn't try to re-evaluate the variable min?
Clarification: I don't want to change the signature. I want the expression tree to avaluate min not as a variable, but as a constant expression. Is there anyway to convert the evaluation of min so that the tree has a constant expression instead of a variable evaluation?
Edit: read your comment, try a function creator.
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));
Try using a 1 element array. Ugly, but it works.
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));
Another option, better:
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));
You would have to make it a parameter.
Expression<Func<List<IUser>, int, bool>> ulContainsJohn =
(List<IUser> l, int min) => (l.Where(u => u.FirstName == "John").Count() > min);
ulContainsJohn.Compile()(userList, min);