首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当我有时想要任何"T“时,我应该使用泛型吗?

当我有时想要任何"T“时,我应该使用泛型吗?
EN

Stack Overflow用户
提问于 2013-02-12 03:02:16
回答 2查看 84关注 0票数 0

我在做一个关于工厂的游戏。工厂里有装满东西的板条箱。有时会有一些仓库,里面装着装有物品的板条箱,工人需要在板条箱中寻找某些类型的物品(例如,工人可能会调用一个函数,询问“仓库中是否有装有食物的板条箱?”,如果有,他就会去拿起它,并将其移动到某个地方。

使用泛型来定义"Crate“和”from“类( Depot继承自这个类)来指定它们包含的对象类型似乎非常有用。下面是我的Crate类和家具类的片段,然后是我的Depot类,我正在努力解决这个问题:

代码语言:javascript
复制
public class Crate<I> : Item 
    where I : Item
{
}

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

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

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

代码语言:javascript
复制
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),因为它会弄乱我的搜索算法-查找食品的板条箱将返回null,因为它只包含项目的板条箱。

我是不是应该保留Crate的泛型,而在StorageFurniture中去掉它们,并让我的搜索算法稍微长一点(即搜索所有的家具,而不仅仅是那些包含正确类型项目的家具),或者有没有办法绕过这个问题?

EN

回答 2

Stack Overflow用户

发布于 2013-02-12 03:14:39

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

代码语言:javascript
复制
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,并放弃泛型

票数 1
EN

Stack Overflow用户

发布于 2013-02-12 03:25:47

如果你的游戏在你的商店里是“自包含的”,这样改变基础类型和重新编译所有东西都不会是一个额外的负担,我建议在你的基础"GameObject“类型中有许多虚拟方法,并有一个字段来指示(通过”标志“枚举)哪些方法将对给定的对象做一些事情,这可能是有利的。如果一个人有一个游戏对象列表,并且想要在该操作相关的列表中的所有对象上执行一些操作(例如,一个炸弹爆炸了,并且想要“损坏”爆炸范围内的所有可损坏的物品),那么无条件地调用一个对所有对象都通用的虚拟方法--甚至是那些它什么也不做的对象--要比测试每个对象是否实现了一个接口,如果是的话,在对象上调用该接口要快得多。

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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14819020

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档