1

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

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

例子:

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

  }

}

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

谢谢!

4

5 回答 5

4

我认为您实际上不需要知道属性背后的对象。使用SetValue方法将其值设置为 "Kaspar":

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

Lion kaspar = new Lion { Name="Kaspar" };
zooType.SetValue(londonZoo, kaspar, null);
于 2011-08-25T16:12:11.037 回答
2

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

它由 2 个函数get和定义set,它们可以做任何你想做的事情,而且根本不需要返回对象的值。

您使用的只是一种语法糖,可以更轻松地制作属性来包装成员。

于 2011-08-25T16:10:13.077 回答
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会生成一个计算值并且没有单一的支持对象。

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

于 2011-08-25T16:09:57.883 回答
1

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

londonZoo.GetProperty("Lion").SetValue(londonZoo, new Lion("Kaspar"), null); 
于 2011-08-25T16:11:46.317 回答
1

首先你需要创建狮子:

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

然后需要设置动物园的 Lion 属性:

lionProperty.SetValue(londonZoo, lion, null);

然后可以得到狮子的 Name 属性:

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

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

if (property != null && property.CanWrite)
{
    property.SetValue(lion, "Kaspar", null);
}
于 2011-08-25T16:38:45.917 回答