2009-09-09 9 views
5

जावा में की तरह मेरे पास है:क्या मैं प्रतिबिंब का उपयोग कर सी # में एक निजी रीडोनली विरासत क्षेत्र बदल सकता हूं?

Class.getSuperClass().getDeclaredFields() 

मैं कैसे पता है और एक सुपर क्लास से निजी क्षेत्र निर्धारित कर सकते हैं?

मुझे पता है कि इसकी दृढ़ता से अनुशंसा नहीं की जाती है, लेकिन मैं अपने आवेदन का परीक्षण कर रहा हूं और मुझे एक गलत स्थिति का अनुकरण करने की आवश्यकता है जहां आईडी सही है और नाम नहीं है। लेकिन यह आईडी निजी है।

उत्तर

9

हाँ, यह प्रतिबिंब का उपयोग करने के एक केवल पढ़ने के लिए फ़ील्ड का मान सेट करने के लिए के बाद निर्माता समाप्त हो गया है संभव है

var fi = this.GetType() 
      .BaseType 
      .GetField("_someField", BindingFlags.Instance | BindingFlags.NonPublic); 

fi.SetValue(this, 1); 

संपादित करें

प्रत्यक्ष अभिभावक प्रकार को देखने के लिए अपडेट किया गया। यदि सामान्य प्रकार हैं तो इस समाधान में समस्याएं होंगी।

+0

लेकिन, इस कोड के साथ मैं मूल क्षेत्र नहीं प्राप्त कर सकता। ठीक है? – Custodio

+0

@ लुइस, पैरेंट प्रकार – JaredPar

+0

में देखने के लिए कोड को अपडेट किया गया है अब मैं केवल " k__BackingField" का उपयोग करके अपना क्षेत्र क्यों प्राप्त कर सकता हूं? – Custodio

1

इस वर्ग आप यह कर देंगे:

http://csharptest.net/browse/src/Library/Reflection/PropertyType.cs

उपयोग:

new PropertyType(this.GetType(), "_myParentField").SetValue(this, newValue); 

Btw, यह सार्वजनिक/गैर सरकारी क्षेत्रों या गुण पर काम करेंगे। इस्तेमाल में आसानी के लिए आप इस तरह व्युत्पन्न वर्ग PropertyValue उपयोग कर सकते हैं:

new PropertyValue<int>(this, "_myParentField").Value = newValue; 
+0

+1 csharptest-net लाइब्रेरी के लिए +1। इसमें एक दिलचस्प लॉगर है। –

1

हाँ, आप कर सकते हैं।

फ़ील्ड के लिए, FieldInfo कक्षा का उपयोग करें। BindingFlags.NonPublic पैरामीटर आपको निजी फ़ील्ड देखने की अनुमति देता है।

public class Base 
{ 
    private string _id = "hi"; 

    public string Id { get { return _id; } } 
} 

public class Derived : Base 
{ 
    public void changeParentVariable() 
    { 
     FieldInfo fld = typeof(Base).GetField("_id", BindingFlags.Instance | BindingFlags.NonPublic); 
     fld.SetValue(this, "sup"); 
    } 
} 

और एक छोटे से परीक्षण साबित करने के लिए यह काम करता है:

public static void Run() 
{ 
    var derived = new Derived(); 
    Console.WriteLine(derived.Id); // prints "hi" 
    derived.changeParentVariable(); 
    Console.WriteLine(derived.Id); // prints "sup" 
} 
0

तरह JaredPar पता चलता है, मैं पालन किया:

//to discover the object type 
Type groupType = _group.GetType(); 
//to discover the parent object type 
Type bType = groupType.BaseType; 
//now I get all field to make sure that I can retrieve the field. 
FieldInfo[] idFromBaseType = bType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance); 

//And finally I set the values. (for me, the ID is the first element) 
idFromBaseType[0].SetValue(_group, 1); 

सभी को धन्यवाद।

+0

मदद मिली है क्या आप सुनिश्चित हैं कि idFromBaseType [0] सही फ़ील्ड है? आपको शायद नाम से मेल खाना चाहिए ... –

+0

मेरे लिए काम करता है, मेरा पहला तत्व आईडी है। लेकिन मैंने बिना किसी सफलता के स्ट्रिंग के साथ फ़ील्ड प्राप्त करने का प्रयास किया है। – Custodio