2012-04-06 18 views
14

में नहीं मिली है जैसा कि .NET Reflection set private property में डिस्क्स्ड किया गया है, कोई एक निजी सेटर के साथ एक संपत्ति सेट कर सकता है। लेकिन जब संपत्ति को बेस क्लास में परिभाषित किया जाता है, तो System.ArgumentException फेंक दिया जाता है: "संपत्ति सेट विधि नहीं मिली"।प्रॉपर्टी सेट विधि व्युत्पन्न प्रकार

एक उदाहरण हो सकता है:

using System; 
class Test 
{ 
    public DateTime ModifiedOn { get; private set;} 
} 

class Derived : Test 
{ 
} 

static class Program 
{ 
    static void Main() 
    { 
     Derived p = new Derived(); 
     typeof(Derived).GetProperty("ModifiedOn").SetValue(
      p, DateTime.Today, null); 
     Console.WriteLine(p.ModifiedOn); 
    } 
} 

किसी को भी इस स्थिति से निपटने के लिए एक तरह से पता है?

संपादित करें: दिया गया उदाहरण समस्या का एक सरल उदाहरण है। असली दुनिया परिदृश्य में, मुझे नहीं पता कि संपत्ति को बेस क्लास में परिभाषित किया गया है, या बेस क्लास के आधार पर परिभाषित किया गया है।

उत्तर

20

मुझे ऐसी ही समस्या थी जहां मेरी निजी संपत्ति को बेस क्लास में घोषित किया गया था। मैंने DeclaringType क्लास पर एक हैंडल प्राप्त करने के लिए उपयोग किया जहां संपत्ति परिभाषित की गई थी।

using System; 
class Test 
{ 
    public DateTime ModifiedOn { get; private set;} 
} 

class Derived : Test 
{ 
} 

static class Program 
{ 
    static void Main() 
    { 
     Derived p = new Derived(); 

     PropertyInfo property = p.GetType().GetProperty("ModifiedOn"); 
     PropertyInfo goodProperty = property.DeclaringType.GetProperty("ModifiedOn"); 

     goodProperty.SetValue(p, DateTime.Today, null); 

     Console.WriteLine(p.ModifiedOn); 
    } 
} 
9

मुझे लगता है कि यह काम करेगा:

using System; 
class Test 
{ 
    public DateTime ModifiedOn { get; private set;} 
} 

class Derived : Test 
{ 
} 

static class Program 
{ 
    static void Main() 
    { 
     Derived p = new Derived(); 
     typeof(Test).GetProperty("ModifiedOn").SetValue(
      p, DateTime.Today, null); 
     Console.WriteLine(p.ModifiedOn); 
    } 
} 

आप वर्ग से संपत्ति परिभाषा प्राप्त करने की आवश्यकता है अपने

संपादित वास्तव में नहीं व्युत्पन्न वर्ग पर परिभाषित:

यह चुनने के लिए, किसी भी बेस क्लास पर आपको सभी माता-पिता वर्गों पर इसकी तलाश करनी होगी।

कुछ इस तरह तो आधार वर्ग के लिए recurse जब तक तुम वस्तु हिट या अपनी संपत्ति को खोजने के

typeof(Derived).GetProperties().Contains(p=>p.Name == "whatever") 
+0

बेस प्रकार ज्ञात होने पर यह निश्चित रूप से काम करेगा। कृपया मेरा संपादन देखें। – tafa

7

@ LukeMcGregor के एक से एक अन्य विकल्प BaseType

typeof(Derived) 
    .BaseType.GetProperty("ModifiedOn") 
    .SetValue(p, DateTime.Today, null); 
+0

हां, यदि विरासत का पेड़ लंबाई का था। कृपया मेरा संपादन देखें। – tafa

+1

फिर आप लाइन पर चलते हैं ... आप सिस्टम पर रोक सकते हैं। ऑब्जेक्ट। –

5
उपयोग करने के लिए है

मैं इस पुन: प्रयोज्य विधि बनाया । यह मेरे परिदृश्य को संभालता है।

private static void SetPropertyValue(object parent, string propertyName, object value) 
    { 
     var inherType = parent.GetType(); 
     while (inherType != null) 
     { 
      PropertyInfo propToSet = inherType.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance); 
      if (propToSet != null && propToSet.CanWrite) 
      { 
       propToSet.SetValue(parent, value, null); 
       break; 
      } 

      inherType = inherType.BaseType; 
     } 
    } 
संबंधित मुद्दे