2015-02-10 23 views
1

我有一個函數返回一個表達式,我傳入一個字段和一個值。我有函數返回StartsWith,但我想回到不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,但後來我得到「參數」!我'沒有綁定「。

我試着搞亂了Expression.Not,似乎無法讓它工作。

+2

向我們展示您使用帶有'Expression.Not'的代碼,解釋,具體是什麼沒有工作。 – Servy 2015-02-10 20:57:30

+0

我真的不知道該怎麼傳遞給Expression.Not,也不知道該怎麼做。 嘗試傳遞參數(無法轉換) parameter = Expression.Not(parameter); 嘗試通過結果表達式(無法轉換) var expr = Expression.Lambda >(body,parameter); expr = Expression.Not(expr) – 2015-02-10 21:01:51

+0

該文檔將告訴您應該傳遞給它的內容,並且它也有示例。你可以根據你想得到的表達式來表達它的邏輯逆。 – Servy 2015-02-10 21:02:56

回答

2

環繞你Expression.CallExpression.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; } 
    } 
}