2010-09-14 20 views
15

के साथ केवल गुणों को पढ़ना बदलना संभव है? प्रतिबिंब या किसी अन्य तरीके से?प्रतिबिंब

+5

एलोडी: यह संभव है, लेकिन * * यह मत करो ** !!! – Gabe

+0

क्या आप केवल संपत्ति के रिटर्न वैल्यू को बदलने की कोशिश कर रहे हैं, या बैकिंग फ़ील्ड का मान जो पढ़ा गया है (जैसे 'निजी रीडोनली इंटी प्राइमेटिव वैल्यू = 1;')? – Elisha

+0

हाय एलोडी, क्या आप या तो अधिक जानकारी का अनुरोध कर सकते हैं, या एक जवाब स्वीकार कर सकते हैं? –

उत्तर

13

जैसा कि अन्य ने कहा है, यदि आपको ऐसा करने की ज़रूरत है, तो आपको शुरुआत करने के लिए एक डिज़ाइन समस्या का सामना करना पड़ रहा है। अब, अगर आप जानना चाहते हैं कि यह जानने के लिए सिर्फ संभव है, या यदि पृथ्वी पर ऐसा करने का कोई अन्य तरीका नहीं है, तो यह वास्तव में संभव है, बहुत कम helper library और एक विस्तार विधि की सहायता से।

निम्नलिखित कोड पर विचार करें:

class Person { 

    int age; 
    string name; 

    public int Age { get { return age; } } 
    public string Name { get { return name; } } 
} 

// ... 

using Mono.Reflection; 
using System.Reflection; 

// ... 

Person person = new Person (27, "jb"); 
PropertyInfo nameProperty = typeof (Person).GetProperty ("Name"); 
FieldInfo nameField = nameProperty.GetBackingField(); 
nameField.SetValue (person, "jbe"); 

इस कोड का उपयोग करना, तुम सिर्फ संपत्ति के साथ एक संपत्ति के समर्थन क्षेत्र मिलता है, और समर्थन क्षेत्र के लिए एक नया मान असाइन कर सकते हैं। आप implementation के बारे में अधिक जानकारी पढ़ सकते हैं।

भी ध्यान रखें कि यह इस तरह के रूप में सरल गुण, के लिए ही काम करता है:

public int Age { get { return age; } } 

public string Name { 
    get { return name; } 
    set { name = value; } 
} 

public double Velocity { get; private set; } 

आप कस्टम कोड के साथ जटिल गुण होते हैं, तो समर्थन क्षेत्र समाधानकर्ता असफल हो जायेगी।

0

यह संपत्ति पर निर्भर करता है। यदि यह एक गणना की गई संपत्ति है - नहीं, जब तक कि आप यह नहीं जानते कि यह किस आधार पर आधारित है। अगर यह सिर्फ एक निजी क्षेत्र के लिए एक एक्सेसर है, तो आप क्षेत्र को संशोधित करने का प्रयास कर सकते हैं।

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

0
PropertyInfo isReadOnly = typeof(System.Collections.Specialized.NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance| BindingFlags.NonPublic); 
//Remove the readonly property 
isReadOnly.SetValue(param, false, null); 

//.............put your code here..... 

// Set readonly property 
isReadOnly.SetValue(param, true, null); 
9

ऑटो के लिए एक बहुत गंदा समाधान के रूप में उत्पन्न केवल गुण पढ़ें:

class MyTestClass 
{ 
    public string MyProperty { get; } 

    public MyTestClass(string MyProperty) 
    { 
     this.MyProperty = MyProperty; 
    } 
} 

आप संशोधित कर सकते हैं स्वत: निम्नलिखित तरीके से समर्थन क्षेत्र उत्पन्न:

MyTestClass MyClass = new MyTestClass("Hello"); 
FieldInfo MyWriteableField = MyClass.GetType().GetRuntimeFields().Where(a => Regex.IsMatch(a.Name, $"\\A<{nameof(MyClass.MyProperty)}>k__BackingField\\Z")).FirstOrDefault(); 
MyWriteableField.SetValue(MyClass, "Another new value"); 

पुनश्च: जब आप एक .NET संस्करण < 4.6 का उपयोग कर रहे हैं, आपको कुछ कोड को काम पर बदलना पड़ सकता है। आनंद लें!

7

साइमन Mattes जवाब देने के लिए एक वैकल्पिक होगा

आप यह मानते हुए है:

public class MyClass 
{ 
    public int MyNumber {get;} 
} 

आप अगर ऐसा कर सकता है इसके परीक्षण उद्देश्य के लिए:

var field = typeof(MyClass).GetField("<MyNumber>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic); 
field.SetValue(anIstanceOfMyClass, 3);