鉴于此代码:
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个“John”,但第二个断言失败。如何热切地将min的值绑定到Func,所以它不会尝试重新评估变量min?
澄清:我不想改变签名。我希望表达式树能够将min作为变量而不是作为常量表达式进行avaluate。是否有转换min的评估,以便树具有常量表达而不是变量评估?
答案 0 :(得分:1)
你必须把它作为一个参数。
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 :(得分:1)
编辑:阅读您的评论,尝试使用函数创建器。
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));
答案 2 :(得分:0)
最简单的解决方案是创建一个单独的变量:
int min = 0;
int staticMin = min;
Func<List<IUser>, bool> ulContainsJohn =
l => l.Where(u => u.FirstName == "John").Count() > staticMin ;