2010-05-07 12 views
7

मैं स्थिति है जहाँ मैं प्रतिबिंब का उपयोग इंटरफ़ेस की विधि कॉल करने के लिए है, इस.NET प्रतिबिंब: उदाहरण बनाये बिना इंटरफेस की विधि कैसे कॉल करें?

object x = null; 
MethodInfo method = interfaceExists.GetMethod("ShutDown"); 
method.Invoke(x, new object[] { 4 }) 

की तरह है आप देख सकते हैं मैं वस्तु का उदाहरण बनाने नहीं है! और, जैसा कि मैं अपेक्षा कर सकते हैं, मैं प्राप्त अपवाद

गैर स्थिर विधि लक्ष्य

और सवाल है, मैं इंटरफ़ेस के कहने बनाए बिना और हाँ अगर प्रतिबिंब का उपयोग इंटरफ़ेस की विधि फोन कर सकते हैं की आवश्यकता है, कैसे मैं यह कर सकता हूं ?

+0

इस बारे में सोचें: यह विधि वास्तव में * क्या करेगी, अगर आप इसे बुला सकते हैं? – Aaronaught

उत्तर

12

इंटरफ़ेस विधि ऑब्जेक्ट स्थिति को प्रभावित नहीं करेगी (और यह आमतौर पर एक बहुत ही खराब धारणा है), आप FormatterServices.GetUnitializedObject पर कॉल करके कन्स्ट्रक्टर को कॉल किए बिना एक उदाहरण बना सकते हैं। निजी तौर पर, मैं इसके खिलाफ दृढ़ता से अनुशंसा करता हूं, क्योंकि जब आप एक प्रारंभिक प्रकार पर इंटरफ़ेस विधि कॉल करते हैं तो किसी भी बुरी चीजें हो सकती हैं।

+3

+1। – Will

+0

धन्यवाद, यह शायद मेरे लिए उचित रूप से है – jitm

10

यदि यह एक उदाहरण विधि है, तो आपको विधि को कॉल करने के लिए एक उदाहरण की आवश्यकता है। इसलिए "उदाहरण" विधि।

इंस्टेंस विधियों में आवृत्ति चर पर निर्भरता हो सकती है, जो प्रतिबिंब के बारे में पता नहीं होगा, इसलिए यह गारंटी नहीं दे सकता कि एक उदाहरण विधि उस प्रकार के उदाहरण की स्थिति को परिवर्तित नहीं करती है जिसमें इसे परिभाषित किया गया है।

यही कारण है कि आप उन FxCop चेतावनियों को यहां प्राप्त करेंगे (यहां पर पैराफ्रेशिंग) "इस विधि को स्थैतिक बनाएं क्योंकि यह कक्षा की स्थिति को परिवर्तित नहीं करता है"।

+0

मैं इंटरफ़ेस स्थिर की विधि कैसे बना सकता हूं? – jitm

+0

आपके पास इंटरफ़ेस पर स्थिर विधियां नहीं हो सकती हैं। आपको कक्षा में एक स्थैतिक विधि की आवश्यकता होगी, यदि आप नहीं चाहते कि कक्षा का उपयोग इसे अमूर्त के रूप में चिह्नित किया जाए, और इंटरफ़ेस को कार्यान्वित किया जाए, तो प्राप्त करें कि आप इससे उप-वर्ग हैं। – Ian

+0

@jitm आप नहीं कर सकते हैं। यदि आप ** वास्तव में वास्तव में ** ऐसा करने की ज़रूरत है, तो बेस क्लास के लिए अपने इंटरफेस को मिटाने पर विचार करें। बेशक, आप बेस क्लास स्थैतिक तरीकों को ओवरराइड नहीं कर सकते हैं, इसलिए आप अभी भी खराब हो सकते हैं।एसओ पर एक और सवाल पूछने का प्रयास करें (इस का उपयोग न करें) जो विवरण आप जो करने की कोशिश कर रहे हैं, और पूछें कि क्या कोई बेहतर तरीका है। – Will

4

यदि विधि गैर स्थैतिक है, तो आपको इसका उपयोग करने के लिए एक ऑब्जेक्ट उदाहरण बनाना होगा। चूंकि इंटरफेस में स्थैतिक विधियां नहीं हो सकती हैं, इसलिए आपको विधि को निष्पादित करने के लिए इंटरफ़ेस के साथ किसी ऑब्जेक्ट का उदाहरण बनाना होगा।

1

एक इंटरफ़ेस में कोई कार्यान्वयन नहीं है, इसलिए आप उस ऑब्जेक्ट को लागू करने वाले ऑब्जेक्ट के उदाहरण के बिना अपनी विधि को कॉल नहीं कर सकते हैं।

2

आपकी गैर स्थैतिक इंटरफ़ेस विधि को अंततः किसी ऑब्जेक्ट पर लागू की गई विधि को कॉल करने की आवश्यकता होगी। यदि विधि का कार्यान्वयन मौजूद नहीं है, तो कोई वास्तविक विधि नहीं कहा जा सकता है।

1

क्या आप एक उदाहरण बनाये बिना एक इंटरफ़ेस विधि कॉल कर सकते हैं? नहीं। इंटरफेस उदाहरण के सदस्यों के लिए हैं; स्थैतिक वर्ग के सदस्य इंटरफेस से संबंधित नहीं हैं।

आप इंटरफ़ेस का एक स्थिर कार्यान्वयन प्रदान करके आप क्या चाहते प्राप्त करने में सक्षम हो सकता है,

public class MyImplementation : IMyInterface 
{ 
    public static readonly Instance = new MyImplementation(); 
    private MyImplementation() { } 
} 
// ...then your code might look like: 
MethodInfo method = typeof(IMyInterface).GetMethod("ShutDown"); 
method.Invoke(MyImplementation.Instance, new object[] { 4 }) 

या आप एक विस्तार विधि बना सकता है: यदि आप पूरी तरह आश्वस्त हैं कि

public static class MyExtensions 
{ 
    public static void ShutDown(this IMyInterface obj, ...) { ... } 
} 
// ...then your code might look like: 
object x = null; 
MethodInfo method = typeof(MyExtensions).GetMethod("ShutDown"); 
method.Invoke(x as IMyInterface, new object[] { 4 }); 
+0

धन्यवाद, मुझे पता है। गुप्त निंजा तकनीकों के लिए – jitm