C#

2010-08-16 13 views
5

yansımasını kullanarak yüklemek için dönüştürün Temel olarak this yapmaya çalışıyorum, ama ne olacağını bilmiyorum, bu yüzden Yansıma ve İfade ağaçları kullanarak bir şeyler yapıyorum.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 }); 

Temelde, bir ben yansıtmaya çalışıyorum List<Book> ve Invoke onun Find yöntem var. Find yönteminin Func<Book, bool> yerine Predicate<Book>'a ihtiyacı var ve kafamı bir kaç saatliğine atıyorum.

Düzenleme:

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

, ben de o sağlayabilmektedir, ama esas olumsuz etkisi olacağını düşündüm sorunun bir parçası. –

cevap

3

Neyse bu sadece Expression.Lambda için çağrı değiştirerek, yapmak oldukça kolaydır:

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

O ne açık değil İşte hata iz ilk bölümüdür Sonuçla ilgin vardı, sakın ... eğer yazılan versiyon sizin için uygunsa, bu iyi olmalı.

+0

Bunu mu demek istediniz: Predicate <,> (virgülle)? –

+0

Şüpheliyim, çünkü sadece 1 tip arg alır. :) –

+0

@Jon: Hayır. Gördüğünüz kodun hangi sürümünü kullandığınızdan emin değilim - en azından birkaç düzeltmeden geçiyordu, kısmen yetersizlik nedeniyle ve kısmen de yanlış bir şekilde soruyu yanlış yorumladı :) –

0

bu Jon'un cevap olarak aynı ise emin değil: Birisi Bul yöntem çağırma bölümü görmek gerekiyorsa

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

Üzgünüz, açıkça tedarik etmek için T'ye sahip olmadığımı belirtmeye çalıştım. Yani, açıkça satır 1 yazılı olmak yerine, Type itemType, çözümünüzün bir parametresi olur. –