c# - 否定表达式

标签 c# linq expression

我有一个返回表达式的函数,我传入一个字段和一个值。我有返回 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/

相关文章:

c# - 使用 maxchar 居中和拆分字符串

c# - 在类中为属性赋值

c# - 有没有一种简单的方法可以替换 Azure 云服务引用 dll,而无需重新发布服务?

c# - 如何从 C# 中的 C++/CLI dll 访问类型?

c# - 为什么 LINQ 方法 Any 不检查计数?

c# - 您必须添加对程序集 mscorlib 的引用,version=4.0.0

ios - 获取零而不是浮点值-Objective C

c++ - x&&y||z 是如何计算的?

clojure - 简化函数输出不完全符合预期

linq - System.Xml.Linq.XElement >' does not contain a definition for ' First' 并且没有扩展方法 'First' 接受第一个参数