2010-07-16 38 views
3

我正在創建一個遊戲,目前正在爲它的庫存系統工作。我有一個類來代表玩家,它看起來像這樣:如何在C#中存儲對屬性的引用?

class Player { 
    public Weapon WeaponSlot {get;set;} 
    public Shield ShieldSlot {get;set;} 
    //etc. 
} 

武器,盾牌等都是通用產品類的子類:

class Item { 
    //... 
} 

class Weapon : Item { 
    //... 
} 

有武器等的子類,但這並不重要。

無論如何,我創建一個用戶控件來顯示/修改一個給定的廣告位的內容。但是,我不確定如何做到這一點。在C++中,我會使用類似:

new InventorySlot(&(player.WeaponSlot)); 

但是,我不能這樣做,在C#。

我發現TypedReference結構,但不工作,因爲你不能使一個字段與結構之一,所以我不能將它存儲用於控制以後。

是反射走的唯一途徑,或者是有一些其他的設施,我不知道的?

編輯----

僅供參考,這裏是我做了什麼:

partial class InventorySlot : UserControl { 
    PropertyInfo slot; 
    object target; 

    public InventorySlot(object target, string field) { 

     slot = target.GetType().GetProperty(field); 

     if (!slot.PropertyType.IsSubclassOf(typeof(Item)) && !slot.PropertyType.Equals(typeof(Item))) throw new //omitted for berevity 

     this.target = target; 

     InitializeComponent(); 
    } 
    //... 
} 

而且,它是這樣的初始化:

new InventorySlot(player, "WeaponSlot"); 

此外,關於性能,我對此不太在意。這不是一個實時遊戲,所以我只需要更新屏幕以迴應玩家的操作。 :)

+0

只是爲了澄清,我有兩個要求: 1.對象,其屬性我想修改有幾個屬性,其名稱是不知道的控制 2.可能有多個不同類別的這樣的對象我想修改。因此,我不能僅僅存儲對象的引用,因爲我無法在運行時間中對其類型進行神聖的描述。 到目前爲止,我正在使用反射,這似乎是要走的路。 – 2010-07-16 18:19:26

+0

閱讀您的評論事實上,您不知道您需要完全做什麼,除非在運行時讓您唯一的選擇是反思。由於這是一款遊戲,因此您需要確保積極緩存反射調用(我建議您查看靜態只讀ConcurrentDictionary,甚至將此數據保存到磁盤或文檔數據庫等)。 – 2010-07-16 18:24:36

+0

在這種情況下,性能不是問題。如果是這樣,我不會使用WinForms :) – 2010-07-16 18:29:32

回答

3

本質你正在創建的是一個屬性瀏覽器。看看Windows Forms的PropertyGrid控件(閱讀文檔以瞭解它如何工作和/或使用Reflector讀取代碼)。

簡單的答案是簡單地使用反射。通過存儲PropertyDescriptor,您可以獲取並設置給定對象實例的屬性成員的值。

+0

聽起來像這樣是要走的路......我想可能有另一種方式,但是謝謝 – 2010-07-16 18:21:51

+0

這真的是要走的路。您不僅可以訪問屬性值,還可以訪問它可能具有的任何元數據(即屬性)。 – Tergiver 2010-07-16 18:41:19

0

class每個類型的對象是在c#的參考。值類型聲明爲struct

因此,例如:

Weapon w1 = new Weapon(); 
w2 = w1;//Does not make a copy just makes a second reference to what w1 is pointing to 

如果你需要一個輸入/輸出參數的功能,您可以使用ref。如果您需要輸出參數,則可以使用out。如果你只是傳遞一個類型爲class的對象的引用,那麼你可以傳遞它並修改類對象本身。

4

我正在創建UserControl至 顯示/修改給定 庫存槽的內容。但是,我不確定 究竟該如何做到這一點。在C++中,I 會使用類似

它按照默認方式工作。 「ref」關鍵字也不需要。

+0

問題是庫存插槽是對象上的屬性,而不是對象本身。我需要(編輯)對財產本身的參考,這隻有通過反思纔有可能。 (這是我去的路線) – 2010-07-21 16:00:36

0

你可以克隆對象,以達到你想要的東西:

public class Weapon : ICloneable 
{ 
    public string Name; 

    object ICloneable.Clone() 
    { 
     return this.Clone(); 
    } 
    public Weapon Clone() 
    { 
     return (Weapon)this.MemberwiseClone(); 
    } 
} 

可以比做這樣的事情來獲取對象的副本與所有的內部值:

Weapon w1 = new Weapon(); 
Weapon w2 = w1.Clone() 
+0

廢棄這個.. :)如果你不想修改實際的對象,這是如何做到的。 – oekstrem 2010-07-16 18:15:56

1

這是默認行爲afaik

0

如果您確實需要參考,則可以使用字段。他們可以被ref引用。

+0

而且,我將如何存儲此參考以供以後使用? – 2010-07-21 15:59:06