2012-04-06 108 views
14

.NET Reflection set private property中所述,可以使用私人setter來設置屬性。但是,當在基類中定義屬性時,會引發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); 
    } 
} 

你需要從類獲得屬性定義其對不派生類實際上定義

編輯:

把它撿起在任何基類中,您將需要在所有父類上查找它。

這樣的事情,然後改乘基類,直到你打對象或找到你的財產

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

如果基本類型是已知的,這肯定會起作用。請參閱我的編輯。 – tafa 2012-04-06 09:21:29

7

比@ LukeMcGregor的一個另一種選擇是使用BASETYPE

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

是的,如果繼承樹長度爲1。請參閱我的編輯。 – tafa 2012-04-06 09:22:39

+1

然後你走這條線......你可以在System.Object停下來。 – 2012-04-06 09:32:20

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; 
     } 
    } 
相關問題