2013-02-11 38 views
0

我正在制作关于工厂的游戏。工厂里的箱子里装着东西。有时候会有仓库包含包含物品的箱子,而且工人需要在箱子里找到某些物品类型(例如,工人可以调用一个函数询问“任何仓库中是否有包含食物的箱子? “,如果是的话,他会去拿它并将它移动到某个地方。有时我需要任何“T”时,是否应该使用泛型?

用泛型定义”Crate“和”Furniture“类(从中继库)来指定哪些类型似乎非常有用。它们所包含的对象下面是我的木箱类和我的家具类的片段,然后我要和我挣扎得宝类:

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进行废弃,并使我的搜索算法稍长一点(即搜索所有Furnitures而不是仅包含那些包含正确类型项目的Furnitures),还是有办法获得围绕这个问题?

+3

考虑将问题重写得更加简洁。我觉得我必须理解整个系统来回答这个问题。 – 2013-02-11 19:05:01

+0

我觉得如果我只是说“我应该什么时候使用泛型”,这个问题就太模糊了。实质上,我希望能够搜索包含包含特定项目的Crates的StorageFurniture。因此,如果StorageFurniture详细说明了需要的项目(有时候这将是'code'输入'代码'),那么这将使查找这些项目和箱子更容易。但是,当某些StorageFurniture可以包含任何类型的箱子时,我不知道如何声明它。 – Haighstrom 2013-02-11 19:16:35

+0

我编辑了你的标题。请参阅:“[应该在其标题中包含”标签“](http://meta.stackexchange.com/questions/19190/)”,其中的共识是“不,他们不应该”。 – 2013-02-11 19:17:08

回答

1

考虑创建一个根类或接口为您的板条箱能够对象:

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 
} 

如果你正在处理木箱-S它才有意义有共同的东西,你会与他们无关 - 打开它们,关闭它们,在它们上面放置标签,丢弃它们,将它们装载到卡车上,卸载它们等。所有这些常见特征都可以在根(抽象?)类或接口中抽象化。

如果您还没有与任何板条箱的预定义的操作,你可能也只是让他们oject而放弃仿制药

+0

问题是搜索特定的箱子。如果我想尝试在其中找到带有食物的箱子,那么现在我的搜索算法对我的工厂中的每个StorageFurniture sf说'',如果sf是StorageFurniture >请检查它中的每个项目以查看它是否可用“。由于仓库(不像其他家具)不能指定它的箱子有什么,所以这会导致一个问题... – Haighstrom 2013-02-11 19:34:41

+0

另外我的“Item”类基本上是你的“ICrateable”,这里不需要接口。箱子只包含物品,但我的问题是我是否应该指定它包含的具体物品,因为没有箱子会同时包含“食物”和“原材料”等。 – Haighstrom 2013-02-11 19:39:57

+0

所以在你的Item类中添加一个方法“SearchOfType (string query)” – 2013-02-12 17:05:10

0

如果你的游戏将是“自足”的店铺内,从而改变基类型和重新编译一切都不会是一个过度的负担,我会建议在你的基类“GameObject”类型中有很多虚拟方法可能是有利的,并且有一个字段可以指示(通过“flags”枚举)哪些方法会对给定的对象做些什么。如果有一个游戏对象列表,并且希望对该列表中与该动作相关的所有对象执行一些动作(例如,炸弹熄灭,并且想要“破坏”爆炸范围内的所有可损坏物品),则无条件地更快调用一个虚拟方法对于所有对象来说是通用的 - 即使是那些什么也不做的地方 - 对于每个对象测试它是否实现了一个接口并在对象上调用该接口(如果是这样的话),都是一样的。

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

如果采用向基类添加虚拟方法来支持将存在于某些但不是所有对象中的能力的方法,可以最小化执行运行时类型转换的需求。这将反过来减少对泛型的需求。在基类变化很麻烦的情况下,“kitchen-sink基类”方法并不好,但在性能很重要的情况下可能会有所帮助,特别是对于存在明智缺省的行为(例如,如果“FlashingStrobe”游戏对象在附近的物体上调用NoticeFlashingStrobe,不关心闪光频闪的物体可能在这种方法中没有任何意义)。

相关问题