परिचय: जब कोड कहता है "मुझे नहीं पता"
\nएक स्थिति की कल्पना करें: आप C# में एक सीरियलाइज़ेशन लाइब्रेरी लिख रहे हैं। आपके पास एक मेथड है Serialize<T>(T obj) जो किसी भी ऑब्जेक्ट को स्ट्रिंग में बदल सकता है। सब कुछ तब तक ठीक है जब तक आप इसे किसी विशिष्ट टाइप के साथ कॉल करते हैं: Serialize<User>(user)। लेकिन क्या होगा अगर ऑब्जेक्ट का टाइप प्रोग्राम के चलने के दौरान ही पता चले?
यह एक क्लासिक समस्या है जो Stack Overflow पर हज़ारों डेवलपर्स पूछते हैं: "How do I call a generic method using a Type variable?"। पहली नज़र में, हल आसान लगता है, लेकिन C# एक सख्ती से टाइप की गई भाषा है, और टाइप वेरिएबल को एंगुलर ब्रैकेट में डालकर काम नहीं चलेगा।
\n\nइस ट्यूटोरियल में, हम सीखेंगे कि C# रिफ्लेक्शन का उपयोग करके MakeGenericMethod के साथ generic मेथड को सही तरीके से कैसे कॉल करें। आप न केवल सिंटैक्स सीखेंगे, बल्कि यह भी जानेंगे कि यह कब वास्तव में ज़रूरी है और कब इसके विकल्प खोजना बेहतर है।
Method<type>() क्यों नहीं लिख सकते?
\nचलिए पहले भ्रम दूर करते हैं। निम्नलिखित कोड कंपाइल नहीं होगा:
\nType runtimeType = someObject.GetType();\n// कंपाइलेशन एरर: "'runtimeType' टाइप मान्य नहीं है"\nSomeMethod<runtimeType>();\n\n\nक्यों? क्योंकि C# में generic पैरामीटर कंपाइल-टाइम मेटाडेटा हैं। कंपाइलर को ठीक-ठीक पता होना चाहिए कि वह किस टाइप के साथ काम कर रहा है ताकि कोड जनरेट कर सके। Type वेरिएबल एक ऑब्जेक्ट है जो केवल runtime में मौजूद होता है। कंपाइलर के लिए यह सिर्फ एक वेरिएबल है, टाइप नहीं।
इसका हल रिफ्लेक्शन के क्षेत्र में है - एक ऐसा मैकेनिज़्म जो runtime के दौरान टाइप के सदस्यों की जांच और कॉल करने की अनुमति देता है।
\n\nचरण-दर-चरण ट्यूटोरियल: Type से Generic Method कॉल करना
\nआइए एक ठोस उदाहरण के साथ समस्या को समझते हैं। मान लीजिए हमारे पास डेटा प्रोसेस करने के लिए एक सर्विस है:
\npublic class DataProcessor\n{\n public string Process<T>(T data)\n {\n return $"प्रोसेस किया {typeof(T).Name}: {data}";\n }\n}\n\n\nहम Process<T> को कॉल करना चाहते हैं जब टाइप T केवल runtime में ज्ञात हो, जैसे typeof(string) या someObject.GetType() से।
चरण 1. Generic Method के लिए MethodInfo प्राप्त करें
\nपहले हमें अपने मेथड को दर्शाने वाला एक ऑब्जेक्ट प्राप्त करना होगा:
\nDataProcessor processor = new DataProcessor();\nType processorType = typeof(DataProcessor);\n\n// नाम से मेथड खोजें। महत्वपूर्ण: अगर मेथड public नहीं है तो BindingFlags दें\nMethodInfo? methodInfo = processorType.GetMethod("Process");\n\n\nमहत्वपूर्ण! अगर आपके पास मेथड के कई ओवरलोड हैं, तो आपको GetMethods() और फ़िल्टरिंग का उपयोग करके खोज को स्पष्ट करना होगा। हमारे मामले में एक ही मेथड है - सब आसान है।
चरण 2. MakeGenericMethod से Generic Method को कंक्रीट बनाएं
\nयह रहा हमारा मुख्य हीरो - MakeGenericMethod मेथड। यह टाइप की एक array लेता है और कंस्ट्रक्टेड (कंक्रीट) मेथड लौटाता है:
Type runtimeType = typeof(int); // या कोई अन्य टाइप जो डायनामिक रूप से प्राप्त हुआ\nMethodInfo? genericMethod = methodInfo?.MakeGenericMethod(runtimeType);\n\n\nअब genericMethod एक पूर्ण मेथड Process<int> है, जो कॉल करने के लिए तैयार है।
चरण 3. Invoke के माध्यम से मेथड को कॉल करें
\nअंतिम चरण - Invoke का उपयोग:
object? result = genericMethod?.Invoke(processor, new object[] { 42 });\nConsole.WriteLine(result); // आउटपुट: "प्रोसेस किया Int32: 42"\n\n\nध्यान दें:
\n- \n
Invokeका पहला पैरामीटर ऑब्जेक्ट का इंस्टेंस है (स्टैटिक मेथड के लिएnull). \n - दूसरा पैरामीटर मेथड आर्गुमेंट्स की array है। भले ही एक ही आर्गुमेंट हो, वह array में होना चाहिए। \n
- परिणाम
object?के रूप में लौटता है - आपको इसे उपयुक्त टाइप में कास्ट करना पड़ सकता है।