2012-04-06 8 views
14

Come modificato in .NET Reflection set private property, è possibile impostare una proprietà con un setter privato. Ma quando la proprietà è definita in una classe base, viene lanciata System.ArgumentException: "Metodo set di proprietà non trovato".Metodo set di proprietà non trovato in un tipo derivato

Un esempio può essere:

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); 
    } 
} 

Qualcuno sa un modo per affrontare questa situazione?

Modifica: L'esempio fornito è una semplice illustrazione del problema. Nello scenario del mondo reale, non so se la proprietà è definita in una classe base, o definita nella base della classe base.

risposta

20

Ho avuto un problema simile in cui la mia proprietà privata è stata dichiarata in una classe base. Ho utilizzato DeclaringType per ottenere un handle sulla classe in cui è definita la proprietà.

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

penso che questo funzionerà:

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); 
    } 
} 

è necessario per ottenere la definizione di proprietà dalla classe la sua realtà definito sulla non la classe derivata

EDIT:

per raccoglierlo su qualsiasi classe base dovrai cercarlo su tutte le classi genitore.

qualcosa di simile quindi recurse alla classe di base fino a colpire oggetto o trovare la vostra proprietà

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

Ciò funzionerebbe sicuramente, se il tipo di base era noto. Si prega di consultare la mia modifica. – tafa

7

Un'altra opzione di una @ di LukeMcGregor è quello di utilizzare BaseType

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

Sì, se l'albero di ereditarietà era di lunghezza uno. Si prega di consultare la mia modifica. – tafa

+1

Quindi si cammina la linea ... È possibile interrompere a System.Object. –

5

ho fatto questo metodo riutilizzabile . Gestisce i miei scenari.

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; 
     } 
    }