我有一个返回表达式的函数,我传入一个字段和一个值。我有返回 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
,但后来我得到“参数 '!i' 不是绑定(bind)”。
我尝试摆弄 Expression.Not,但似乎无法让它工作。
最佳答案
用Expression.Not
包围你的Expression.Call
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; }
}
}
关于c# - 否定表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28441590/