2010-07-15 6 views
26

में एक समारोह कॉल करने के लिए मैं विधि है:कैसे गतिशील #

add(int x,int y) 

और मैं भी है:

int a=5; 
int b=6; 
string s="add"; 

यह संभव है कॉल करने के लिए जोड़ने के (ए, बी) स्ट्रिंग s का उपयोग करके? मैं इसे सी # में कैसे कर सकता हूं?

+5

'if (s ==" add ") {add (a, b); } 'यह? – dtb

+0

मुझे लगता है कि वह जावास्क्रिप्ट के 'eval()' फ़ंक्शन के समान कुछ ढूंढ रहा है, जो मुझे नहीं लगता कि यह C# में मौजूद है। लेकिन मैं उत्सुकता से यह देखने का इंतजार कर रहा हूं कि जॉन स्कीट इस पर कैसे वजन करता है। –

+0

संभावित डुप्लिकेट [स्ट्रिंग के रूप में फ़ंक्शन नाम पास करके किसी भी फ़ंक्शन को गतिशील रूप से आमंत्रित करना] (http://stackoverflow.com/questions/801070/dynamically-invoking-any-function-by-passing-function-name-as-string) – kennytm

उत्तर

48

मैं इसे सी # में कैसे कर सकता हूं?

प्रतिबिंब का उपयोग करना।

add, कुछ प्रकार के एक सदस्य हो गया है तो (विस्तार का एक बहुत बाहर काटने):

typeof(MyType).GetMethod("add").Invoke(null, new [] {arg1, arg2}) 

इसमें यह माना जाता add स्थिर (Invoke को अन्यथा पहला तर्क वस्तु है) है और मैं डॉन ' GetMethod कॉल में विधि को विशिष्ट रूप से पहचानने के लिए अतिरिक्त पैरामीटर की आवश्यकता नहीं है।

+1

+1। धन्यवाद, मैंने अभी इसे अपने कोड में इस्तेमाल किया है। अगर किसी और के पास मेरी कठिनाइयों की स्थिति है, तो यह निजी कार्यों के साथ काम नहीं करता है। – David

+0

@ डेविडस्ट्रैटन यह 'निजी' सदस्यों के साथ काम करेगा: ['GetMethod'] (http://msdn.microsoft.com/en-us/library/05eey4y9.aspx) के अधिभारों में से एक का उपयोग करें जो एक [' बाइंडिंगफ्लैग लेता है) '] (http://msdn.microsoft.com/en-us/library/system.reflection.bindingflags.aspx) 'बाइंडिंगफ्लैग्स नॉनपब्लिक' के साथ तर्क। – Richard

+0

क्या हम रीफेक्शन के बजाय "Func <>" का उपयोग कर सकते हैं? – Sreekumar

19

उपयोग प्रतिबिंब - कोशिश Type.GetMethod विधि

तरह
MethodInfo addMethod = this.GetType().GetMethod("add"); 
object result = addMethod.Invoke(this, new object[] { x, y }); 

आप मजबूत टाइपिंग खो देते हैं और संकलन समय की जाँच - आह्वान कितने मापदंडों विधि की उम्मीद है, और क्या उनके प्रकार पता नहीं है क्या हैं और वापसी मूल्य का वास्तविक प्रकार क्या है। तो यदि आप इसे सही नहीं पाते हैं तो चीजें रनटाइम पर असफल हो सकती हैं।

यह भी धीमा है।

10

आप प्रतिबिंब का उपयोग कर सकते हैं।

using System; 
using System.Reflection; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Program p = new Program(); 
      Type t = p.GetType(); 
      MethodInfo mi = t.GetMethod("add", BindingFlags.NonPublic | BindingFlags.Instance); 
      string result = mi.Invoke(p, new object[] {4, 5}).ToString(); 
      Console.WriteLine("Result = " + result); 
      Console.ReadLine(); 
     } 

     private int add(int x, int y) 
     { 
      return x + y; 
     } 
    } 
} 
11

यदि फ़ंक्शंस संकलन समय पर ज्ञात हैं और आप बस एक स्विच स्टेटमेंट लिखने से बचना चाहते हैं।

सेटअप:

Dictionary<string, Func<int, int, int>> functions = 
    new Dictionary<string, Func<int, int, int>>(); 

functions["add"] = this.add; 
functions["subtract"] = this.subtract; 

द्वारा कहा जाता है:

string functionName = "add"; 
int x = 1; 
int y = 2; 

int z = functions[functionName](x, y); 
0

@ रिचर्ड का जवाब बहुत अच्छा है। बस इसे थोड़ा विस्तार करने के लिए:

यह एक ऐसी स्थिति है जहां आप गतिशील रूप से अज्ञात प्रकार का ऑब्जेक्ट बनाया में उपयोगी हो सकता है और इसकी विधि कॉल करने की जरूरत है:

क्योंकि संकलन समय do पर
var do = xs.Deserialize(new XmlTextReader(ms)); // example - XML deserialization 
do.GetType().GetMethod("myMethodName").Invoke(do, new [] {arg1, arg2}); 

सिर्फ एक Object है ।

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