2010-06-07 7 views
25

नीचे दिया गया कोड बहुत अच्छा काम करता है। यदि Get और Use विधियां विभिन्न असेंबली में हैं, तो कोड RuntimeBinderException के साथ विफल रहता है। ऐसा इसलिए है क्योंकि नेट रनटाइम सिस्टम केवल असेंबली के भीतर अज्ञात प्रकारों (<string, int>) की समानता की गारंटी देता है।विधानसभा सीमाओं में गतिशील अनाम प्रकार को वापस/उपभोग करें

क्या इस पर काबू पाने के लिए रनटाइम सिस्टम को बेवकूफ बनाने का कोई तरीका है? मैं Use पक्ष पर डीबगर में ऑब्जेक्ट का निरीक्षण कर सकता हूं, और डीबगर प्रासंगिक गुण देख सकता है।

class Program 
{ 
    static void Main(string[] args) 
    { 
     UsePerson(); 
     Console.ReadLine(); 
    } 

    public static void UsePerson() 
    { 
     var person = GetPerson(); 

     Console.WriteLine(person.Name); 
    } 

    public static dynamic GetPerson() 
    { 
     return new { Name = "Foo", Age = 30 }; 
    } 
} 

उत्तर

31

अज्ञात प्रकार के बजाय ExpandoObject का उपयोग करें। यह आप सुरक्षित रूप से विधानसभा सीमाओं को पार करने की अनुमति चाहिए:

public static dynamic GetPerson() 
{ 
    dynamic person = new ExpandoObject(); 
    person.Name = "Foo"; 
    person.Age = 30; 

    return person; 
} 

सामान्य, अनाम प्रकार में वास्तव में केवल एक ही तरीका है जिसमें वे उत्पन्न कर रहे हैं के भीतर किया जाना चाहिए। एक विधि से एक अनाम प्रकार लौटाना सामान्य रूप से, हल होने की तुलना में अधिक समस्याएं पैदा करने जा रहा है।

8

समस्या का कारण यह है कि अज्ञात प्रकार असेंबली के लिए आंतरिक हैं। यही कारण है कि गतिशील भाषा रनटाइम आपको किसी अन्य असेंबली से गुणों तक पहुंचने की अनुमति नहीं देता है।

इस समाधान को post में समझाया गया है। आप असेंबली में एक कस्टम विशेषता डाल सकते हैं जो अज्ञात प्रकार को परिभाषित करता है जिससे अन्य असेंबली अपने आंतरिक तक पहुंचने की इजाजत देता है।

एक और समाधान सार्वजनिक वर्ग (सार्वजनिक संपत्तियों के साथ) की वस्तु को वापस कर रहा है। वह, निश्चित रूप से, गुमनाम प्रकार के फायदे को मार देगा।

एक तीसरा समाधान का उपयोग करेगा जैसा कि रीड कॉपसे द्वारा सुझाया गया है।

यदि आप अभी भी अनाम प्रकार का उपयोग करना चाहते हैं, तो आप एक गतिशील वर्ग लिख सकते हैं जो किसी भी अज्ञात प्रकार को "सजाने" और अपने सदस्यों को उजागर करता है। इस तरह के एक वर्ग को IDynamicMetaObjectProvider इंटरफ़ेस को कार्यान्वित करना होगा और प्रतिबिंबित के माध्यम से सजाए गए ऑब्जेक्ट को एक्सेस करना होगा। संभवतः, यह सामान पहले से किसी के द्वारा लागू किया गया था।

+0

पोस्ट को इंगित करने वाला लिंक –

+1

उपरोक्त पोस्ट में समाधान "1" वास्तव में बहुत दिलचस्प है। असल में [असेंबली: InternalsVisibleTo ("SomeOtherAssembly")] आपके assemblyinfo.cs में बहुत अच्छी तरह से काम करता है। – OFConsulting

0

अचानक इंटरफ़ेस

http://code.google.com/p/impromptu-interface/

आप सीमाओं के पार गुमनाम प्रकार उदाहरण का उपयोग करते हैं जाएगा लेकिन आपको एक ऐसा इंटरफ़ेस घोषित करना होगा जो उसके हस्ताक्षर से मेल खाता हो या कम से कम आप इसके हस्ताक्षर से क्या पहुंचाना चाहते हैं।

1

यहां एक गरीब व्यक्ति का कामकाज है; न्यूटॉन्सॉफ्ट.जेसन बचाव के लिए, क्योंकि सीरियलाइजेशन राउंडट्रिप आपके/काम करने वाली असेंबली के लिए दिखाई देने वाले गतिशील प्रकार के उदाहरण उत्पन्न करता है।

public static class TypeExt 
{ 
    // roundtrip json serialization to enable access to dynamic members and properties originating from another assembly 
    public static T JClone<T>(this T source) { return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source)); } 
} 
संबंधित मुद्दे