1

私はゲームを書いていますが、クレートによって異なるタイプ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

2 に答える 2

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>>またはそのようなものが必要になる場合があります。

于 2013-02-12T08:06:50.180 に答える
2

派生型が数個しかない場合は、派生型ごとに動的キーワードと関数のオーバーロードを使用するか、リフレクションを使用してこれを行うことができます(Jon Skeetの回答を参照)。

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

// ... and in your code:

Add(CreateButton((dynamic)(GV.CurrentlyAvailableItems[i])));
于 2013-02-12T08:17:05.860 に答える