2012-04-06 9 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); 
    } 
} 

あなたはクラスからプロパティ定義が、実際にはない派生クラス

EDIT上で定義されて取得する必要があります。それを選ぶために

どの基本クラスでも、すべての親クラスでそれを探す必要があります。 LukeMcGregorの1が、私はこの再利用可能な方法を作ったBaseType

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

基本タイプがわかっていれば、これは間違いなく機能します。私の編集を見てください。 – tafa

7

に別のオプションをあなたの財産を見つけます。私のシナリオを処理します。

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

はい、継承ツリーは、長さ1であった場合。私の編集を見てください。 – tafa

+1

そして、あなたがラインを歩く...あなたはSystem.Objectので停止することができます。 –

5

を使用することです@よりも、このような

何かは、あなたがオブジェクトを打つまでの基底クラスに再帰または

typeof(Derived).GetProperties().Contains(p=>p.Name == "whatever") 
関連する問題