2012-11-26 24 views
7

क्या System.Reflection.MethodInfoIDisposable.Dispose के कार्यान्वयन के लिए निम्नलिखित के मुकाबले एक अधिक औपचारिक/असफल तरीका है?जांचें कि क्या विधि IDISposable लागू करती है। प्रतिबिंब के साथ निपटें

System.Reflection.MethodInfo methodInfo; 
methodInfo = ...; //methodInfo obtaining code here 
bool isDisposeMethod = methodInfo.Name == "Dispose"; 

मैं पहले से ही पता वर्ग को लागू करता है IDisposable और इस तरह कि Dispose मौजूद है, लेकिन मैं एक PostSharp पहलू यह है कि विशेष कार्यशीलता प्रदर्शन करना चाहिए जब Dispose कहा जाता है (किसी अन्य वर्ग विधि की तुलना में) का उपयोग कर रहा हूँ।

+1

यदि कोई वर्ग 'आईडीस्पोजेबल' लागू करता है, तो आपको गारंटी है कि यह 'निपटान' लागू करता है - यह इंटरफ़ेस का बिंदु है। – Blorgbeard

+0

मैं इसे समझता हूं। मुझे पता है कि 'निपटान' मौजूद है, लेकिन मैं एक पोस्टशर्प पहलू का उपयोग कर रहा हूं जिसे एक अलग फ़ंक्शन की तुलना में 'निपटान' कहा जाता है जब विशेष कार्यक्षमता निष्पादित करनी चाहिए। PostSharp पहलू 'System.Reflection.MethodInfo' में विधि हस्ताक्षर लौटाता है। –

उत्तर

6

होने:

class DisposableObject : IDisposable 
{ 
    public void Dispose() 
    { 
     //... 
    } 
} 

आप कर सकते हैं:

Type t = typeof(DisposableObject); 

InterfaceMapping m = t.GetInterfaceMap(typeof(IDisposable)); 
MethodInfo mi = t.GetMethod("Dispose"); 

Console.WriteLine(mi == m.TargetMethods[0]); //true 

तो, मुझे लगता है कि आप अपनी कक्षा में कुछ Dispose विधि के लिए MethodInfo है (यहाँ mi, बस GetMethod(string) के माध्यम से)। तो Type.GetInterfaceMap Method के माध्यम से आपको घोषित प्रकार (DisposableObject) में IDisposable कार्यान्वयन के लिए InterfaceMapping Structure ऑब्जेक्ट प्राप्त करने की आवश्यकता होगी। वास्तव में इंटरफेस को लागू करने वाले तरीकों का संदर्भ देने के लिए आपके पास TargetMethods है। इसलिए, हमें केवल यह जांचने की आवश्यकता है कि आपका संदर्भ m.TargetMethods[0] के बराबर है IDisposable केवल एक विधि घोषित करता है।

MSDN से:

InterfaceMapping संरचना

एक वर्ग कि है कि इंटरफ़ेस को लागू करता है पर वास्तविक तरीकों में एक इंटरफेस की मैपिंग पुन: प्राप्त करता।

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

इंटरफ़ेस मैपिंग संरचना प्राप्त करने के लिए, Type.GetInterfaceMap विधि का उपयोग करें।


एक टिप्पणी: यदि आपका वर्ग IDisposable स्पष्ट रूप से लागू कर सकता है, तो m.TargetMethods[0] स्पष्ट implemetation संदर्भ होगा। इसलिए, मुझे यकीन नहीं है कि InterfaceMapping को छोड़कर Use Reflection to find Methods that implement explicit interfaces को छोड़कर कोई भी तरीका है या नहीं। यह स्थिति त्रुटि प्रवण हो सकती है। इसे अपने विशिष्ट मुद्दे के लिए जांचें।

+0

आपके उत्तर के लिए धन्यवाद। मैं यह जांचने की कोशिश नहीं कर रहा हूं कि ऑब्जेक्ट 'आईडीस्पोजेबल' लागू करता है - यह सिर्फ 'बूल टेस्ट = myObj IDISpoable है' - मैं यह जांचने की कोशिश कर रहा हूं कि कोई विशिष्ट 'MethodInfo'' आईडीआईस्पोजेबल के 'कार्यान्वयन' को संदर्भित करता है। । –

+0

@ फ़ैबियन मैंने अपना जवाब संपादित कर लिया है, कृपया इसकी समीक्षा करें – horgh

+0

इसके लिए धन्यवाद, यह बहुत अच्छा लग रहा है! –

4

मुझे लगता है कि सही तरीके से GetInterface("IDisposable") पर सही तरीका है और फिर इंटरफ़ेस ऑब्जेक्ट के आधार पर विधि जानकारी प्राप्त करें। इंटरफ़ेस से लौटाई गई विधि के साथ आप विधि की तुलना करने की तुलना में सक्षम होना चाहिए।

बस जाँच नाम पर्याप्त नहीं

रूप
  • वहाँ ही नाम के साथ अन्य तरीकों लेकिन अलग तर्क
  • इंटरफ़ेस explcitly लागू किया जा सकता हो सकता है।

यहाँ वर्ग दोनों मुद्दों से पता चलता है जो:

class Test : IDisposable 
{ 
    public void Dispose(){} 
    public void Dispose(bool flag){} 
    void IDisposable.Dispose(){} 
} 
3

मुझे लगता है कि यह अपने मामले, इसकी नहीं सुंदर कोड में काम कर सकते हैं, लेकिन यह आपके विधि की जानकारी एक IDisposible वर्ग से आता है, तो वापस आ जाएगी।

System.Reflection.MethodInfo methodInfo; 
methodInfo = ...; //methodInfo obtaining code here 
bool isDisposible = methodInfo.DeclaringType.FindInterfaces(new System.Reflection.TypeFilter((type, filter) => { return type.ToString() == filter.ToString(); }), "System.IDisposable").Any(); 

सुनिश्चित नहीं है कि यह आपके बाद क्या है।

+0

यह भी एक अच्छा जवाब है। मैंने एक साथ रोल किया है कि आप और कॉन्स्टेंटिन वासिलकोव दोनों ने एक साथ क्या रखा है: 'बूल isDisposible = methodInfo.DeclaringType.GetInterfaceMap (टाइपऑफ (आईडीस्पोजेबल))। TargetMethods.Where (x => x == methodInfo) .एन(); ' –

+2

आप ऊपर दी गई विधि में" कहां "खंड छोड़ सकते हैं और बस उपयोग करें: ' बूल isDisposible = methodInfo.DeclaringType.GetInterfaceMap (टाइपऑफ (IDISposable))। TargetMethods.Any (x => x == methodInfo) ; ' –