2010-08-16 4 views
5

में प्रतिबिंब का उपयोग करके पूर्वानुमान करने के लिए func को कनवर्ट करें मैं मूल रूप से this करने की कोशिश कर रहा हूं, लेकिन मुझे नहीं पता कि टी क्या होगा, इसलिए मैं प्रतिबिंब और अभिव्यक्ति पेड़ों का उपयोग करके चीजों का निर्माण कर रहा हूं।सी #

// 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>, जो मैं पर प्रतिबिंबित करने की कोशिश कर रहा हूँ और Invoke अपने Find विधि है। Find विधि को की बजाय Predicate<Book> की आवश्यकता है, और मैं कुछ घंटों के लिए इसके खिलाफ अपना सिर मार रहा हूं।

संपादित करें:

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

कोई हिस्सा है जहाँ मैं विधि आह्वान को देखने के लिए की जरूरत है, मैं भी है कि आपूर्ति कर सकते हैं, लेकिन मैंने सोचा कि यह आवश्यक में कोई कमी होगी प्रश्न का हिस्सा –

उत्तर

3

सौभाग्य से यह करने के लिए बहुत आसान है, बस Expression.Lambda करने के लिए अपने कॉल बदलकर है:

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

यह क्या स्पष्ट नहीं कर रहा है यहाँ त्रुटि ट्रेस का पहला हिस्सा है आपको परिणाम के साथ करने की ज़रूरत है, आपको दिमाग ... अगर कमजोर टाइप किए गए संस्करण आपके लिए ठीक है, तो यह ठीक होना चाहिए।

+0

क्या आप <,> (अल्पविराम के साथ) लिखना चाहते थे? –

+0

मुझे शक है, क्योंकि यह केवल 1 प्रकार का तर्क लेता है। :) –

+0

@ जोन: नहीं। मुझे यकीन नहीं है कि आपने जो कोड देखा है, वह कम से कम कुछ संपादन के माध्यम से आ गया है, आंशिक रूप से अक्षमता के कारण और आंशिक रूप से प्रश्न को गलत तरीके से पढ़ने के कारण :) –

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

क्षमा करें, मैंने यह बताने की कोशिश की कि मेरे पास स्पष्ट रूप से आपूर्ति करने के लिए टी नहीं है। तो वास्तव में लाइन 1 को स्पष्ट रूप से लिखा गया है, टाइप टाइप टाइप टाइप आपके समाधान के लिए एक पैरामीटर होगा। –