2011-08-25 85 views
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

我不认为你真的需要知道背后的对象属性。使用SetValue方法来将其值设置为“卡斯帕”:

编辑 - 按dlev的评论,这是应该的样子:

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

'zooType'是一个'Type'对象;你需要在'londonZoo'上设置值。然而,这也不起作用,因为你不能将一个'string'赋值给'Animal'类型的属性。 – dlev

+0

@dlev - 非常真实。 –

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产生的计算值,并且没有单个支撑对象。

您列出的情况是用于自动属性。有可能通过挖掘字段并使用名称匹配的形式来获取支持给定自动属性的方法。然而,这样的解决方案对于版本控制将是脆弱的,当然不会推荐。

+0

从他给他说'通过反射Lion.Name =“卡斯帕”来管理这个'这样的例子我不认为他真的想要进入私人领域,只是使用财产的二传手。虽然我可能是错的。 – Chris

+0

@Chris来自帖子的标题,虽然我假设他想要实际的支持对象。这就是我如何解释“到达物业背后的物体”至少 – JaredPar

+0

是的,我当然明白你为什么如此回答。我只是认为他可能根据这个问题有一个垃圾标题。因为我评论过,虽然我见过其他人已经给出了答案,所以我的评论并不重要。 :) – Chris

2

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

它由2个函数定义,getset,它可以做任何你想做的事情,而不一定返回对象的值。

您使用的仅仅是一个语法糖,使其更容易制作属性来包装成员。

1

你可以添加一个重载的构造函数,以你的动物对象,这将让你在动物名称传递,这样?:

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

'zooType'是一个'Type'对象;你需要在'londonZoo'上设置值。然而,这也不起作用,因为你不能将一个'string'赋值给'Animal'类型的属性。 – dlev

+0

哦,我明白了。保持一秒钟。 –

1

首先,你需要创建狮子:

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

然后,你需要设置动物园中的狮子属性:

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