2012-03-16 12 views
6

POCO के लिए एक माइक्रोसॉफ्ट ऑफिस वस्तु के लिए एक नक्शाकार बनाने के लिए कोशिश कर रहा है और इसप्रतिबिंब वस्तुओं

// doesn't work 
// returns an empty array where o is a RCW on an office object 
foreach(var pi in o.GetType().GetProperties()) 
    tgt.SetValue(rc, pi.GetValue(o, null)); 

पाया तो यह

foreach(var field in tgt.GetFields()){ 
    var pv = o.InvokeMember(field.Name, System.Reflection.BindingFlags.GetProperty, null, o, null); 
    i.SetValue(rc, pv); 
} 

जो अब लेकिन सोच क्यों लिए काम करता है का सहारा लेना है RCW.GetProperties() यहाँ काम नहीं करता है?

उत्तर

17

इस लेखन के रूप में अन्य दो उत्तरों सही हैं, लेकिन वे एक COM ऑब्जेक्ट के देर से बाध्यकारी .NET प्रकार प्रणाली के संदर्भ में कैसे दिखते हैं, यह समझाने का एक महत्वपूर्ण अवसर याद करते हैं। जब आप COM ऑब्जेक्ट पर GetType पर कॉल करते हैं, तो वापसी मान __ComObject आंतरिक प्रकार है, COM इंटरफ़ेस प्रकार नहीं जो आप आम तौर पर इंटरऑप कोड लिखते समय काम करते हैं। आप इसे डीबगर में देख सकते हैं, या Console.WriteLine(o.GetType().Name); जैसे कुछ कोड के साथ।

__ComObject प्रकार में कोई गुण नहीं है; यही कारण है कि जब आप o.GetType().GetProperties() पर कॉल करते हैं तो आपको खाली सरणी मिलती है। (कम से कम कुछ चीजें जीवन में समझ में आती हैं!)

यदि आप InvokeMember विधि को संकुचित करते हैं, तो आप पाएंगे कि COM COM ऑब्जेक्ट्स के लिए विशेष हैंडलिंग है, जो एक आंतरिक मूल विधि को कॉल का प्रतिनिधि है। "नियमित" .NET ऑब्जेक्ट्स के लिए, विधि "नियमित" .NET प्रतिबिंब का उपयोग करती है, अनुरोधित सदस्य के लिए उपयुक्त MemberInfo पुनर्प्राप्त करने और इसे आविष्कार करने के लिए।

आप इंटरफ़ेस प्रकार पर .NET प्रतिबिंब का उपयोग कर सकते हैं। उदाहरण के लिए, यदि आप जानते हैं कि ऑब्जेक्ट एक एक्सेल Worksheet है, तो आप typeof(Worksheet).GetProperties() का उपयोग कर सकते हैं और परिणामी PropertyInfo उदाहरणों को अपने ऑब्जेक्ट के साथ उपयोग कर सकते हैं। यदि आप संकलन समय पर ऑब्जेक्ट के प्रकार को नहीं जानते हैं, तो आपको अपने उदाहरण कोड में GetType() पर कॉल करने की आवश्यकता है। उस स्थिति में, आप InvokeMember का उपयोग कर अटक गए हैं।

3

ऐसा इसलिए है क्योंकि COM ऑब्जेक्ट हाल ही में बाध्य है। रन टाइम को पता नहीं है कि COM ऑब्जेक्ट पर कौन सी विधियां/गुण उपलब्ध होंगे जब तक उन्हें एक्सेस/इनवॉक्ड नहीं किया जाता है।

यहाँ इस विषय पर कुछ अच्छा लेख हैं:

http://support.microsoft.com/default.aspx?scid=kb;en-us;Q302902

http://www.codeproject.com/Articles/10838/How-To-Get-Properties-and-Methods-in-Late-Binding

1

आप जानते हुए भी क्या गुण एक हाल ही में समयबद्ध वस्तु का कोई रास्ता नहीं होगा क्योंकि Type.InvokeMember(propertyName, BindingFlags.GetProperty, binder, target, args) का उपयोग कर उन्हें नाम से निर्दिष्ट करने की आवश्यकता संकलन समय पर है। इसके बजाए, आपको रनटाइम पर आमतौर पर स्ट्रिंग तुलना के माध्यम से उस लुकअप को निष्पादित करने की आवश्यकता होती है।

RCW.GetProperties() केवल तभी काम करेगा यदि आप संकलन-समय पर गुणों और उनके स्थानों को निर्धारित कर सकते हैं।