2012-12-21 14 views
5

यह प्रतिबिंब का उपयोग करने में मेरा पहला प्रयास है। प्रवेश करें। मैं एक प्रदान की गई वस्तु के लिए गतिशील रूप से प्रॉक्सी बना रहा हूं। प्रॉक्सी किसी भी सार्वजनिक संपत्ति प्रदान की गई वस्तु के माध्यम से गुजरती है। त्रुटि मैं प्राप्त कर रहा हूँ है:प्रतिबिंब का उपयोग करके किसी अन्य ऑब्जेक्ट से संपत्ति मूल्य प्राप्त करें।

वस्तु 'ProxyObject' पर

संपत्ति एक्सेसर 'AccessorName' निम्न अपवाद दिए: अभिगम विधि 'NS.CoreObject.get_AccessorName को विधि' ProxyObject.get_AccessorName() 'द्वारा प्रयास() अनुत्तीर्ण होना।

जो मैं मान सकता हूं और इकट्ठा कर सकता हूं, यह स्वचालित रूप से जेनरेट की गई संपत्ति गेटटर विधि निजी और छिपी हुई होने के कारण होगा। लेकिन मैं MethodBuilder का उपयोग करके इस पर कैसे काम करूं?

Create DynamicMethod to assign value to a property? पर पोस्ट के अनुसार, आप लक्ष्य मॉड्यूल के साथ "संबद्ध" होने की विधि घोषित करके एक डायनामिक मोड के साथ कर सकते हैं, लेकिन मुझे एक पूर्ण श्रेणी बनाने की आवश्यकता है। क्या कोई समकक्ष "एसोसिएशन" है जिसे प्रतिबिंब के माध्यम से हासिल किया जा सकता है। प्रवेश करें?

यह एक बुनियादी ऑपरेशन है जिसे मैं करने की कोशिश कर रहा हूं, इसलिए मुझे यकीन है कि यह कुछ प्रत्यक्ष और सरल है जिसे मैं अनजान हूं।

+0

यह विधिAccessException है। यह निश्चित रूप से संपत्ति की तरह लगता है वास्तव में सार्वजनिक नहीं है। इस काम को पहले सी # में बनाएं, आईएल आपको इससे मिलेगा, यह आपके उत्सर्जन कोड में भी बहुत उपयोगी होगा। –

+0

बेशक, सार्वजनिक संपत्ति का मतलब कुछ भी नहीं है जब आपकी कक्षा सार्वजनिक नहीं है। मेरे सिर में, इस प्रकार को उसी मॉड्यूल में परिभाषित किया जा रहा था। फिर भी एक और * "मैंने इस पर घंटों बर्बाद कर दिया?" * पल। – redman

उत्तर

9

MethodBuilder के साथ: आप नहीं कर सकते। आप पहुंच के सामान्य नियमों के अधीन हैं। हालांकि, आप DynamicMethod के माध्यम से धोखा दे सकते हैं, जो आपको दिखाए जाने की विधि देता है (यदि आपके पास पर्याप्त पहुंच है) कि आप जिस विधि को बना रहे हैं वह वास्तव में किसी दिए गए प्रकार (या दिए गए मॉड्यूल, आदि) की स्थिर विधि है। यह आपको स्वतंत्र रूप से उदाहरण के लिए निजी राज्य, उपयोग कर सकते हैं इसका मतलब है:

using System; 
using System.Reflection; 
using System.Reflection.Emit; 

public class Foo 
{ 
    public Foo(int bar) 
    { 
     Bar = bar; 
    } 
    private int Bar { get; set; } 
} 
static class Program { 
    static void Main() 
    { 
     var method = new DynamicMethod("cheat", typeof(int), 
      new[] { typeof(object) }, typeof(Foo), true); 
     var il = method.GetILGenerator(); 
     il.Emit(OpCodes.Ldarg_0); 
     il.Emit(OpCodes.Castclass, typeof(Foo)); 
     il.Emit(OpCodes.Callvirt, typeof(Foo).GetProperty("Bar", 
      BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic 
      ).GetGetMethod(true)); 
     il.Emit(OpCodes.Ret); 
     var func = (Func<object, int>)method.CreateDelegate(
      typeof(Func<object, int>)); 

     var obj = new Foo(123); 
     Console.WriteLine(func(obj)); 
    } 
} 

यदि आप हैं केवल संपत्ति का मूल्य प्राप्त है, यह भी ध्यान दिया जाना चाहिए कि Delegate.CreateDelegate, स्वचालित रूप से एक ही कर सकते हैं गेटर के माध्यम से विधि:

var method = typeof(Foo).GetProperty("Bar", 
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) 
    .GetGetMethod(true); 
var func = (Func<Foo, int>) 
    Delegate.CreateDelegate(typeof(Func<Foo, int>), method); 
+0

समझ में आता है (और रचनात्मक भी है)। अगर मैं टाइपबिल्डर के माध्यम से एक प्रकार का निर्माण कर रहा हूं, तो क्या मैं टाइपबल्डर-निर्मित प्रकार में आपके उत्तर द्वारा उत्पन्न आईएल प्राप्त करने में सक्षम हूं? या दोनों पारस्परिक रूप से अनन्य हैं? – redman

+0

@redman एक ही आईएल प्राप्त करने में मदद नहीं करेगा। टाइपबिल्डर * अभी भी * मानक पहुंच के लिए प्रतिबंधित है। आईएल स्तर पर आप * ** * के बारे में * पूछ सकते हैं ** ** अभी भी पहले उपयोग पर जांच की जाएगी। –

+0

मुझे अभी एहसास हुआ कि मेरे प्रश्न का हिस्सा संदिग्ध था। जिन गुणों को मैं एक्सेस करने का प्रयास कर रहा हूं वे * सार्वजनिक * हैं। यह स्वचालित रूप से जेनरेट किए गए एक्सेसर्स हैं जो नहीं हैं। (मैंने इसे प्रतिबिंबित करने के लिए अपना प्रश्न अपडेट कर दिया है।) तो इस विचार के साथ, क्या विधिबिल्डर के माध्यम से किसी अन्य ऑब्जेक्ट की संपत्ति का उपयोग करना आसान है? – redman

संबंधित मुद्दे

 संबंधित मुद्दे