2013-02-12 43 views
1

我正在寫一個遊戲,並且我有一個箱子類,它包含由箱子變化的類型T的Item-s。我和泛型這樣此設置:泛型 - 我可以寫一個基於變量的T嗎?

public class Crate<I> : Item 
    where I : Item 
{ 
    private List<I> contents = new List<I>(); 
    //... 
} 

我目前正在寫「買入」的屏幕,在這裏你選擇的項目,然後將這些物品的箱子交付。根據玩家在遊戲中的階段,某些項目不可用。因此,我有一個數組中當前可用項目的列表。

我想要做的是創建基於該數組的箱子。

例如,我的數組可能是

public static List<Item> CurrentlyAvailableItems= new List<Item>() { new Linen(), new Food() }; 

從這裏,我想創建按鈕來生成這些項目的包裝箱。此刻,我能想到的唯一辦法做到這一點是一個巨大的IF環路需要更新,我每次創建新的項目,如這一次:

for (int i = 0; i < GV.CurrentlyAvailableItems.Count; i++) 
{ 
    Item item = null; 
    if (GV.CurrentlyAvailableItems[i] is Linen) item = new Crate<Linen>(); 
    else if (GV.CurrentlyAvailableItems[i] is Food) item = new Crate<Food>(); 
    Add(new BuyButton(item)); 
} 

我希望能夠做的是一樣的東西:

for (int i = 0; i < GV.CurrentlyAvailableItems.Count; i++) 
{ 
    Type t = GV.CurrentlyAvailableItems[i].GetType(); 
    Crate<t> crate = new Crate<t>(); 
    Add(new BuyButton(crateToBuy)); 
} 

這可能嗎?

回答

4

你可以用反射做到這一點:

// TODO: Consider using a foreach loop over GC.CurrentlyAvailableItems 
Type itemType = GV.CurrentlyAvailableItems[i].GetType(); 
Type crateType = typeof(Crate<>).MakeGenericType(t); 
Item crate = (Item) Activator.CreateInstance(crateType); 
Add(new BuyButton(crate)); 

注意這不會是非常有效的 - 但它可能是不夠好。如果不是,你可能需要一個Dictionary<Type, Func<Item>>或類似的東西。

+0

十分感謝 - 字典可能要走的路,即使它會需要更新,因爲我添加新的類。 – Haighstrom 2013-02-12 08:22:26

2

您可以用動態的關鍵字和函數重載每個派生類型做,如果你只有幾個人,或與反思(見喬恩斯基特的答案):

BuyButton CreateButton(MyDerivedItem foo) 
{ 
    return new BuyButton(Crate<MyDerivedItem>()); 
} 

// ... and in your code: 

Add(CreateButton((dynamic)(GV.CurrentlyAvailableItems[i]))); 
相關問題