我有一个返回表达式的函数,我传入一个字段和一个值。我有返回StartsWith的函数,但我想返回NOT StartsWith
private Expression<Func<T, bool>> GenerateFieldDoesNotStartsWithExpression<T>(string fieldName, string value) {
var parameter = Expression.Parameter(typeof(T), "i");
var fieldAccess = Expression.PropertyOrField(parameter, fieldName);
MethodInfo method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
var passedValue = Expression.Constant(value, typeof(string));
var body = Expression.Call(fieldAccess, method, passedValue);
var expr = Expression.Lambda<Func<T, bool>>(body, parameter);
return expr;
}
返回i.[fieldName].StartsWith(value)
,但我正在寻找
!i.[fieldName].StartsWith(value)
。
我尝试了一些设置,例如设置parameter = !i
和第二个参数设置为i
,但接下来我得到了参数&#39;!i&#39;没有约束&#34;。
我试过搞乱Expression.Not,似乎无法让它发挥作用。
答案 0 :(得分:3)
使用Expression.Call
Expression.Not
var body = Expression.Not(Expression.Call(fieldAccess, method, passedValue));
您的密码:
private Expression<Func<T, bool>> GenerateFieldDoesNotStartsWithExpression<T>(string fieldName, string value)
{
var parameter = Expression.Parameter(typeof(T), "i");
var fieldAccess = Expression.PropertyOrField(parameter, fieldName);
MethodInfo method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
var passedValue = Expression.Constant(value, typeof(string));
// Wrapped Expression.Call with Expression.Not
var body = Expression.Not(Expression.Call(fieldAccess, method, passedValue));
var expr = Expression.Lambda<Func<T, bool>>(body, parameter);
return expr;
}
测试代码:
[TestFixture]
public class ExpressNotTests
{
[Test]
public void GenerateFieldDoesNotStartsWithExpression_DoesNotStartWith_True()
{
var a = new TestClass() {TestString = "Not"};
var exp = GenerateFieldDoesNotStartsWithExpression<TestClass>("TestString", "Test");
var res = exp.Compile()(a);
res.Should().BeTrue();
}
[Test]
public void GenerateFieldDoesNotStartsWithExpression_DoesStartsWith_False()
{
var a = new TestClass() {TestString = "TestString"};
var exp = GenerateFieldDoesNotStartsWithExpression<TestClass>("TestString", "Test");
var res = exp.Compile()(a);
res.Should().BeFalse();
}
private class TestClass
{
public string TestString { get; set; }
}
}