0

我正在制作一个关于工厂的游戏。工厂里装满了东西的板条箱被搬来搬去。有时会有包含装有物品的板条箱的仓库,并且工作人员需要在可用的板条箱中查找某些类型的物品(例如,工作人员可能会调用一个函数,询问“任何仓库中是否有任何装有食物的板条箱? ”,如果是这样,他会去捡起它并把它移到某个地方。

用泛型定义“Crate”和“Furniture”类(从 Depot 继承)来指定它们包含的对象类型似乎非常有用。下面是我的 Crate 类和 Furniture 类的片段,然后是我正在努力解决的 Depot 类:

public class Crate<I> : Item 
    where I : Item
{
}

public abstract class Furniture<I>
    where I : Item
{
}

public class Depot : Furniture<Crate<???>>
{
    //...
}

泛型在这里很有用,因为我可以编写如下搜索方法:

public I FindItem<I,F>
 where I:Item
 where F:Furniture<I>
{
    //pseudocode

    //foreach (furniture f in the factory);
    //if (f is F) foreach (I i in f)
    //if (i.IsAvailable) return i;

    //return null;
}

现在,我的问题是,与大多数其他家具不同,仓库可以携带装有任何东西的板条箱(例如,食物板条箱和原材料板条箱)。但我不能只指定 Crate(Item),因为它会弄乱我的搜索算法 - 寻找 Crates of Food 将返回 null,因为它只包含 Crates of Items。

我是否应该为 Crate 保留泛型但为 StorageFurniture 废弃它们,并使我的搜索算法稍长一些(即搜索所有家具,而不仅仅是那些包含正确类型项目的家具),还是有办法解决这个问题?

4

2 回答 2

1

考虑为 Crate-able 对象创建一个根类或接口:

public class Crate<I> : Item 
    where I : Item
{
    private int capacity;
    private List<I> contents;
    //... and so on
}

public interface ICrateable{
// define common features such as name, ID, description etc here
}

public class Shirt: ICrateable{
// implement interface
}


public class DepotSlot : StorageFurniture<Crate<ICrateable>>
{
    // now you can add any Crate<XYZ> here
}

如果您正在处理 Crate-s,那么只有对它们进行常用操作才有意义——打开它们、关闭它们、在它们上面贴标签、丢弃它们、将它们装载到卡车上、卸载它们等等。所有这些常见的可以在根(抽象?)类或接口中抽象特征。

如果您没有对板条箱进行任何预定义操作,您不妨制作它们oject并放弃泛型

于 2013-02-11T19:14:38.647 回答
0

如果您的游戏将在您的商店中“自成一体”,这样更改基本类型和重新编译所有内容都不会造成过多负担,我建议在基本“GameObject”类型中拥有许多虚拟方法可能是有利的,并且有一个字段可以指示(通过“标志”枚举)哪些方法将对给定对象执行某些操作。如果一个人有一个游戏对象列表,并且想要对该列表中与该操作相关的所有对象执行某些操作(例如,炸弹爆炸并且想要“损坏”爆炸范围内的所有可损坏物品),那么无条件更快调用一个虚方法对所有对象来说都是通用的——即使是那些它什么都不做的对象——而不是测试每个对象是否实现了一个接口,如果是,就在该对象上调用该接口。

在某些情况下,具有指示哪些类型的调用与对象相关的字段可以通过允许系统避免在虚拟方法调用之前执行一些工作来提高性能。例如,如果测试一个字段会显示一个对象不会对TakeBombDamage调用做任何事情,那么就不必浪费时间来计算该对象将受到的伤害量。

如果采取向基类添加虚拟方法以支持将出现在某些但不是所有对象中的能力的方法,则可以最大限度地减少执行运行时类型转换的需要。这反过来将减少对泛型的需求。“kitchen-sink 基类”方法在更改基类很麻烦的情况下并不好,但在性能很重要的情况下可能会有所帮助,特别是对于存在合理默认值的行为(例如,如果“FlashingStrobe”游戏对象调用NoticeFlashingStrobe附近的对象,不关心闪烁频闪的对象可能在这种方法中明智地什么都不做)。

于 2013-02-11T19:25:46.877 回答