2011-09-14 5 views
17

के रूप में कार्यवाही करता है, आप निम्न विधि को निष्पादित करने के लिए प्रतिबिंब का उपयोग करने के बारे में कैसे जाएंगे जब प्रकार को रनटाइम पर केवल अनुमानित किया जा सकता है?एक जेनेरिक विधि को सक्रिय करने के लिए कैसे करें जो पैरामीटर

MainObject.TheMethod<T>(Action<OtherObject<T>>) 
रोजमर्रा के इस्तेमाल में

, आम तौर पर:

mainObject.Method<Message>(m => m.Do("Something")) 

तो, प्रकार की एक सूची को देखते हुए, मैं उपरोक्त विधि में टी के लिए उन्हें स्थानापन्न और आह्वान करने के लिए की जरूरत है।

यह वह जगह है जहाँ मैं पोटीन की ओर रुख करने के लिए मेरे सिर से पहले मिल गया:

var mapped = typeof(Action<OtherObject<>>).MakeGenericType(t.GetType()); 
Activator.CreateInstance(mapped, new object[] { erm do something?}); 

typeof(OtherObject) 
    .GetMethod("TheMethod") 
    .MakeGenericMethod(t.GetType()) 
    .Invoke(model, new object[] { new mapped(m => m.Do("Something")) }); 

अद्यतन: स्पष्टीकरण के लिए, मैं प्रकार की एक सूची है और मैं प्रत्येक के लिए OtherObject का एक ही ज्ञात विधि पर अमल करना चाहते हैं । छद्म कोड:

foreach(var t in types) 
{ 
    mainObject.TheMethod<t>(mo => mo.Do("Something")) 
} 

(TheMethod के लिए पैरामीटर के प्रकार() Action<OtherObject<T>> है के रूप में ऊपर कहा गया है)

FluentNHibernate.Automapping.AutoPersistenceModel Override<T>(System.Action<AutoMapping<T>> populateMap) 

कार्रवाई अब AutoMapping<T>.Where("something")

model.Override<Message>(m => m.Where("DeletedById is null")) 

की ही है, इसे प्रकार के गुच्छा के लिए करें :)

+2

हमेशा कार्रवाई के शरीर में एक ही है, यानी हमेशा 'm.Do है (" समथिंग ")'? –

+0

हां यह है, –

+0

से ऊपर कुछ स्पष्टीकरण जोड़ा गया है क्या मेरा उत्तर आपकी मदद नहीं करता है? –

उत्तर

3

आप अभिव्यक्तियों का उपयोग करके इसे हल कर सकते हैं:

foreach(var t in types) 
{ 
    var mapped = typeof(AutoMapping<>).MakeGenericType(t); 

    var p = Expression.Parameter(mapped, "m"); 
    var expression = Expression.Lambda(Expression.GetActionType(mapped), 
             Expression.Call(p, mapped.GetMethod("Do"), 
             Expression.Constant("Something")), p); 

    typeof(SomeOtherObject).GetMethod("TheMethod").MakeGenericMethod(t) 
          .Invoke(model, new object[] { expression.Compile() }); 
} 

अद्यतन: पूरा काम कर रहे उदाहरण (LINQPad में पेस्ट करें और इसे चलाने):

void Main() 
{ 
    var types = new []{typeof(string), typeof(Guid)}; 
    SomeOtherObject model = new SomeOtherObject(); 
    foreach(var t in types) 
    { 
     var mapped = typeof(AutoMapping<>).MakeGenericType(t); 

     var p = Expression.Parameter(mapped, "m"); 
     var expression = Expression.Lambda(
          Expression.GetActionType(mapped), 
          Expression.Call(p, mapped.GetMethod("Do"), 
          Expression.Constant("Something")), p); 

     typeof(SomeOtherObject).GetMethod("TheMethod") 
           .MakeGenericMethod(t) 
           .Invoke(model, 
             new object[] { expression.Compile() }); 
    } 
} 

class AutoMapping<T> 
{ 
    public void Do(string p) 
    { 
     Console.WriteLine(typeof(T).ToString()); 
     Console.WriteLine(p); 
    } 
} 

class SomeOtherObject 
{ 
    public void TheMethod<T>(Action<AutoMapping<T>> action) 
    { 
     var x = new AutoMapping<T>(); 
     action(x); 
    } 
} 
+0

देर से प्रतिक्रिया के लिए खेद है। इसे जगह में रखा है। मुझे इस पर अपेक्षित प्रकार मिल रहा है: var mapped = typeof (एक्शन <ऑटोमैपिंग <>>)। MakeGenericType (टी); –

+0

आप किस .NET संस्करण का उपयोग कर रहे हैं? और क्या आप मुझे पूरा त्रुटि संदेश दे सकते हैं? मुझे लगता है कि यह एक संकलन त्रुटि है? –

+0

@BobTodd: कृपया अपडेट कोड देखें। इसे इस्तेमाल करे। –

संबंधित मुद्दे