2011-01-19 21 views
14

का उपयोग कर एक स्थिर अधिभारित विधि पर प्रतिबिंब मुझे प्रतिबिंब के माध्यम से आउट पैरामीटर के साथ ओवरलोडेड स्थैतिक विधि का आह्वान करने के साथ कुछ समस्याएं आ रही हैं और कुछ पॉइंटर्स की सराहना करेंगे।आउट पैरामीटर

मैं System.Int32 या System.Decimal जैसे गतिशील रूप से एक प्रकार का निर्माण करने के लिए देख रहा हूं, और फिर उस पर स्थिर TryParse(string, out x) विधि का आह्वान करता हूं।

नीचे कोड दो मुद्दे हैं:

  • t.GetMethod("TryParse", new Type[] { typeof(string), t }) MethodInfo वापस जाने के लिए मैं उम्मीद

  • mi.Invoke(null, new object[] { value.ToString(), concreteInstance }) सफल होने के लिए प्रकट होता है लेकिन पार्स मूल्य के लिए बाहर परम concreteInstance निर्धारित नहीं करता है विफल रहता है

इस फ़ंक्शन में इंटरवॉवन आप कुछ अस्थायी कोड देख सकते हैं जो दिखाता है कि क्या होना चाहिए कलम अगर type पैरामीटर System.Decimal पर सेट किया गया था।

public static object Cast(object value, string type) 
{ 
    Type t = Type.GetType(type); 
    if (t != null) 
    { 
     object concreteInstance = Activator.CreateInstance(t); 
     decimal tempInstance = 0; 

     List<MethodInfo> l = new List<MethodInfo>(t.GetMethods(BindingFlags.Static | BindingFlags.Public)); 

     MethodInfo mi; 
     mi = t.GetMethod("TryParse", new Type[] { typeof(string), t }); //this FAILS to get the method, returns null 
     mi = l.FirstOrDefault(x => x.Name == "TryParse" && x.GetParameters().Length == 2); //ugly hack required because the previous line failed 
     if (mi != null) 
     { 
      try 
      { 
       bool retVal = decimal.TryParse(value.ToString(), out tempInstance); 
       Console.WriteLine(retVal.ToString());  //retVal is true, tempInstance is correctly set 
       object z = mi.Invoke(null, new object[] { value.ToString(), concreteInstance }); 
       Console.WriteLine(z.ToString());   //z is true, but concreteInstance is NOT set 
      } 
      catch (Exception ex) 
      { 
       Debug.WriteLine(ex.Message); 
      } 
     } 

     return concreteInstance; 
    } 

    return value; 
} 

क्या मैं सुनिश्चित करने के लिए है कि मेरे t.GetMethod() कॉल रिटर्न सही MethodInfo क्या करना होगा? मुझे concreteInstance सही ढंग से मेरे mi.Invoke() कॉल में सेट करने के लिए क्या करने की आवश्यकता है?

मुझे पता है कि इस विषय पर कई सवाल हैं, लेकिन उनमें से अधिकतर स्थिर जेनेरिक तरीकों या स्थैतिक विधियों को शामिल करते हैं जिन्हें अधिभारित नहीं किया जाता है। This question समान है लेकिन डुप्लिकेट नहीं है।

उत्तर

26

आप सही BindingFlags का उपयोग करें और out और ref मापदंडों के लिए Type.MakeByRefType उपयोग करने के लिए की जरूरत है। एक सेकंड, और मेरे पास आपके लिए एक कोड नमूना होगा।

उदाहरण के लिए

,

MethodInfo methodInfo = typeof(int).GetMethod(
    "TryParse", 
    BindingFlags.Public | BindingFlags.Static, 
    Type.DefaultBinder, 
    new[] { typeof(string), typeof(int).MakeByRefType() }, 
    null 
); 

मैं कहना चाहिए कि यह लागू भी एक छोटे से मुश्किल है। यहां बताया गया है कि आप इसे कैसे करते हैं।

string s = "123"; 
var inputParameters = new object[] { "123", null }; 
methodInfo.Invoke(null, inputParameters); 
Console.WriteLine((int)inputParameters[1]); 

पहले null है, क्योंकि हम एक स्थिर विधि (वहाँ कोई वस्तु इस मंगलाचरण "प्राप्त" है) लागू कर रहे हैं। nullinputParameters में पार्स के परिणामस्वरूप TryParse द्वारा हमारे लिए "भरा" जाएगा (यह out पैरामीटर है)।

+0

ग्रेट उत्तर, धन्यवाद @ जेसन। – slugster

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