Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 泛型-我可以基于变量写T吗?_C#_Generics - Fatal编程技术网

C# 泛型-我可以基于变量写T吗?

C# 泛型-我可以基于变量写T吗?,c#,generics,C#,Generics,我在写一个游戏,我有一个板条箱类,里面有T型的物品,随板条箱的不同而变化。我已经用类似这样的泛型设置了它: public class Crate<I> : Item where I : Item { private List<I> contents = new List<I>(); //... } for (int i = 0; i < GV.CurrentlyAvailableItems.Count; i++) {

我在写一个游戏,我有一个板条箱类,里面有T型的物品,随板条箱的不同而变化。我已经用类似这样的泛型设置了它:

public class Crate<I> : Item 
    where I : Item
{
    private List<I> contents = new List<I>();
    //...
}
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));
}
我现在正在写一个购买屏幕,在那里你可以选择商品,然后运送一箱箱的商品。根据玩家在游戏中所处的阶段,某些物品可用/不可用。因此,我有一个数组中当前可用项的列表

我想做的是基于该阵列创建板条箱

例如,我的数组可能是

    public static List<Item> CurrentlyAvailableItems= new List<Item>() { new Linen(), new Food() };
从这里,我想创建按钮来生成这些物品的板条箱。目前,我能想到的唯一方法是使用一个巨大的IF循环,每当我创建新项目时,它都需要更新,如下所示:

public class Crate<I> : Item 
    where I : Item
{
    private List<I> contents = new List<I>();
    //...
}
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 ));
}

这可能吗?

您可以通过反射来实现:

// 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));

请注意,这不会非常有效,但可能已经足够好了。如果不是,您可能需要一本字典或类似的东西。

您可以使用反射:

// 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));

请注意,这不会非常有效,但可能已经足够好了。如果不是,您可能需要一个字典或类似的东西。

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

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

// ... and in your code:

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

如果只有少数派生类型,则可以使用每个派生类型的dynamic关键字和函数重载,或者使用reflection(反射)执行此操作参见Jon Skeet的答案:

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

// ... and in your code:

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

非常感谢-字典可能是一种方式,尽管它需要在我添加新类时更新。非常感谢-字典可能是一种方式,尽管它需要在我添加新类时更新。