2012-04-06 110 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; 
     } 
    } 
相关问题