2010-08-16 18 views
5

我基本上試圖做this,但我不知道T是什麼,所以我使用反射和表達式樹來構建事物。將func轉換爲在C#中使用反射的謂詞

// Input (I don't know about "Book") 
Type itemType = typeof(Book); 

// Actual Code 
// Build up func p => p.AuthorName == "Jon Skeet" 
ParameterExpression predParam = Expression.Parameter(itemType, "p"); 
Expression left = Expression.Field(predParam, itemType.GetField("AuthorName")); 
Expression right = Expression.Constant("Jon Skeet", typeof(string)); 
Expression equality = Expression.Equal(left, right); 
Delegate myDelegate = Expression.Lambda(equality, new ParameterExpression[] { predParam }).Compile(); // Not sure if I need this 

// Build up predicate type (Predicate<Book>) 
Type genericPredicateType = typeof(Predicate<>); 
Type constructedPredicateType = genericPredicateType.MakeGenericType(new Type[] { itemType }); 

// I need an instance to use this predicate, right? (** This Fails **) 
object predicateInstance = Activator.CreateInstance(constructedPredicateType, new object[] { myDelegate }); 

基本上,我有一個List<Book>,這我想反思和InvokeFind方法。 Find方法需要一個Predicate<Book>而不是Func<Book, bool>,而且我幾個小時以來一直在毆打我的頭。

編輯:這裏是錯誤跟蹤的第一部分:

System.MissingMethodException: Constructor on type 'System.Predicate`1[[MyProject.Book, MyProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' not found. 
+0

如果有人需要看到我調用查找方法的一部分,我也可以提供,但我認爲它會在必要的減損問題的一部分。 – 2010-08-16 16:44:20

回答

3

還好,這是很容易做到,只需通過改變您的來電Expression.Lambda

Type predicateType = typeof(Predicate<>).MakeGenericType(itemType); 
LambdaExpression lambda = Expression.Lambda(predicateType, equality, predParam); 
Delegate compiled = lambda.Compile(); 

目前還不清楚是什麼你需要處理結果,關注你......如果弱類型版本對你來說沒問題,那應該沒問題。

+0

您的意思是輸入謂詞<,>(用逗號分隔)? – 2010-08-16 16:54:22

+0

我對此表示懷疑,因爲它只需要1個參數。 :) – 2010-08-16 16:58:27

+0

@Jon:不,我不確定你看到的是哪個版本的代碼 - 它經歷了至少一些編輯,部分原因是由於無能,部分原因是由於誤讀了這個問題:) – 2010-08-16 16:59:13

0

不知道這是否是一樣的喬恩的答案:

public static Predicate<T> GetPredicate<T>() 
{ 
    Type itemType = typeof(T); 
    ParameterExpression predParam = Expression.Parameter(itemType, "p"); 
    Expression left = Expression.Field(predParam, itemType.GetField("AuthorName")); 
    Expression right = Expression.Constant("Jon Skeet", typeof(string)); 
    Expression equality = Expression.Equal(left, right); 
    Func<T, bool> function = (Func<T, bool>)Expression.Lambda(equality, new[] { predParam }).Compile(); 
    return new Predicate<T>(function); 
} 
+0

對不起,我試圖傳達我沒有T明確提供。因此,而不是實際上有第1行寫明確,類型itemType將是您的解決方案的參數。 – 2010-08-16 17:02:57

相關問題