是否有办法通过反射获得属性背后的对象?
我正在尝试管理一个属性的动态设置。
的例子:
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");
}
}
我应该在上面的注释部分添加哪些行?
谢谢!
我认为你实际上不需要知道属性背后的对象。使用SetValue方法将其值设置为"Kaspar":
编辑-根据dlev的评论,它应该是这样的:
Lion kaspar = new Lion { Name="Kaspar" };
zooType.SetValue(londonZoo, kaspar, null);
属性后面不一定有对象
它是由两个函数get
和set
定义的,它们可以做任何你想做的事情,而不一定返回对象的值。
您所使用的只是一个语法糖,以便更容易地使用属性来包装成员。
不,您不能使用反射明确地获得任意属性后面的对象。很大程度上是因为不能保证每个属性都绑定到一个对象。它也可以是一个计算值。
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
产生一个计算值,没有单一的支持对象。
您所列出的案例是针对auto-properties的。可能有一种方法可以挖掘字段并使用某种形式的名称匹配来获得支持给定auto-property的字段。然而,这样的解决方案在版本控制方面很脆弱,当然不推荐使用。
你能给你的动物对象添加一个重载的构造函数,这样你就可以像这样传入动物的名字了吗?:
londonZoo.GetProperty("Lion").SetValue(londonZoo, new Lion("Kaspar"), null);
首先需要创建狮子:
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);
}