如何通过反射到达属性背后的“对象”?

时间:2011-08-25 16:05:52

标签: c# .net reflection propertyinfo

有没有办法通过反射获取属性背后的对象?

我正在尝试管理属性的动态设置。

示例:

class Animal
{
  public string Name {get;set;}
  public string Family {get;set;}
}

class Zoo
{
 public Animal Lion {get;set;}
 public Animal Panda {get;set;}
}


class Test
{
   public void SetLionNameWithReflection()
  {

    Zoo londonZoo = new Zoo();
    Type zooType = typeof(Zoo);
    PropertyInfo lionProperty = zooType.GetProperty("Lion");

    // Now what to write here so that I can manage to set Lion's name to Kaspar?
    // (to manage this by reflection Lion.Name = "Kaspar");

  }

}

我应该在上面的注释部分添加更多行?

谢谢!

5 个答案:

答案 0 :(得分:4)

我认为你实际上不需要知道财产背后的对象。使用SetValue方法将其值设置为“Kaspar”:

编辑 - 根据dlev的评论,这应该是这样的:

Lion kaspar = new Lion { Name="Kaspar" };
zooType.SetValue(londonZoo, kaspar, null);

答案 1 :(得分:2)

属性不一定有“后面”的对象。

它由2个函数getset定义,可以执行任何操作,而不一定返回对象的值。

您使用的只是一种语法糖,可以更容易地创建一个属性来包装成员。

答案 2 :(得分:1)

不,你不能使用反射来明确地获取任意属性背后的对象。很大程度上是因为并不能保证每个属性都绑定到一个对象。它可以很容易地成为计算值。

public class Student {
  public string m_firstName;
  public string m_lastName;

  public string FullName {
    get { return String.Format("{0} {1}", m_firstName, m_lastName); }
  }
}

在这种情况下,属性FullName生成一个计算值,并且没有单个支持对象。

您列出的案例是针对自动属性的。可能有一种方法可以挖掘字段并使用名称匹配的形式来获得支持给定自动属性的形式。然而,这样的解决方案对于版本控制来说是脆弱的,当然也不会推荐。

答案 3 :(得分:1)

你能为你的动物对象添加一个重载的构造函数吗,这样你就可以传递动物名字了吗?:

londonZoo.GetProperty("Lion").SetValue(londonZoo, new Lion("Kaspar"), null); 

答案 4 :(得分:1)

首先你需要创造狮子:

var lion = Activator.CreateInstance(lionProperty.PropertyType);

然后你需要设置动物园的L​​ion属性:

lionProperty.SetValue(londonZoo, lion, null);

然后你可以得到狮子的名字属性:

PropertyInfo property = lion.GetType().GetProperty("Name", 
    BindingFlags.Public | BindingFlags.Instance);

然后你可以设置它的名字:

if (property != null && property.CanWrite)
{
    property.SetValue(lion, "Kaspar", null);
}