泛型 - 我可以根据变量编写T吗?

时间:2013-02-12 08:02:20

标签: c# generics

我正在写一个游戏而且我有一个Crate类,其中包含T类型的Item-s。我用Generics这样设置了这个:

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

我正在编写一个“购买”屏幕,您可以在其中选择项目,然后交付这些项目的包装箱。根据玩家在游戏中的阶段,某些项目是不可用的。因此,我有一个数组中当前可用项目的列表。

我想要做的是根据该数组创建Crates。

例如,我的数组可能是

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

从这里,我想创建按钮来生成这些项目的Crates。目前我能想到的唯一方法是使用一个巨大的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 ));
}

这可能吗?

2 个答案:

答案 0 :(得分: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>>或类似的东西。

答案 1 :(得分:2)

如果只有少数派生类型,或者使用反射(参见Jon Skeet的答案),你可以使用动态关键字和函数重载来实现每个派生类型:

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

// ... and in your code:

Add(CreateButton((dynamic)(GV.CurrentlyAvailableItems[i])));