2011-10-13 141 views
2

那麼,我試圖做的是使用表達式樹的集合中的謂詞應用到每個值(讀地圖或list.All(謂語))。看來,我沒有得到的輸入參數綁定到所有提供的值謂詞,我有點卡住了。下面是我用::C#表達式樹綁定

public class SomeType 
{ 
    public IEnumerable<bool> Collection { get; set; } 
} 

void Main() 
{ 
    var list = new SomeType { 
    Collection = new List<bool> { true, true, true } 
    }; 
    var functor = Compiler((SomeType t) => t.Collection, (bool x) => x); 
    functor(list).Dump(); 
} 

MethodInfo FindMethod<TInput>(Type location, string name) 
{ 
    var handle = location 
     .GetMethods(BindingFlags.Static | BindingFlags.Public) 
     .Where(method => method.Name == name).First(); 

    return handle.MakeGenericMethod(typeof(TInput)); 
} 

Predicate<TObject> Compiler<TObject, TProperty>(
    Expression<Func<TObject, IEnumerable<TProperty>>> selector, 
    Expression<Predicate<TProperty>> predicate) 
{ 
    var query = FindMethod<TProperty>(typeof(Enumerable), "All"); 
    var expression = Expression.Call(query, 
     new Expression[] { 
      Expression.Invoke(selector, selector.Parameters), 
      Expression.Lambda<Func<TProperty, bool>>(predicate.Body, 
         Expression.Parameter(typeof(TProperty))), 
     });   

    return Expression.Lambda<Predicate<TObject>>(expression, 
     selector.Parameters).Compile(); 
} 

感謝和抱歉工作,如果這是在另外一個問題(我看了一會兒)回答的代碼(使用linqpad)。

回答

1

這並不工作,但我不得不改變Predicate<TObject>Func<TObject, bool>。如果你想我可以嘗試改回它。

static Predicate<TObject> Compiler<TObject, TProperty>(
    Expression<Func<TObject, IEnumerable<TProperty>>> selector, 
    Expression<Func<TProperty, bool>> predicate) 
{ 
    var query = FindMethod<TProperty>(typeof(Enumerable), "All"); 
    var expression = Expression.Call(
     query, 
     Expression.Invoke(selector, selector.Parameters), 
     predicate); 

    return Expression 
     .Lambda<Predicate<TObject>>(expression, selector.Parameters) 
     .Compile(); 
} 

在5分鐘後......如果你真的想用Predicate<TObject> ...

static Predicate<TObject> Compiler<TObject, TProperty>(
    Expression<Func<TObject, IEnumerable<TProperty>>> selector, 
    Expression<Predicate<TProperty>> predicate) 
{ 
    var query = FindMethod<TProperty>(typeof(Enumerable), "All"); 

    var predicateAsFunc = Expression.Lambda<Func<TProperty, bool>>(
     predicate.Body, 
     predicate.Parameters); 

    var expression = Expression.Call(
     query, 
     Expression.Invoke(selector, selector.Parameters), 
     predicateAsFunc); 

    return Expression 
     .Lambda<Predicate<TObject>>(expression, selector.Parameters) 
     .Compile(); 
} 
+0

我不知道爲什麼我不只是傳遞謂詞參數(嘆氣)。是的,我必須使用謂詞,因爲它已經嚴重依賴到代碼的其餘部分。謝謝! – Bashwork

+0

@Bashwork如果你需要我縮短一點。現在我重複使用'select.Parameters'(少一行) – xanatos