2011-08-25 45 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); 
}