我正在学习编程,我不得不创建一个蛇游戏。
在游戏中,蛇有大约5种可能的消耗品,我决定将每个新的Consumable
放在Consumable
阵列中。
现在我想在数组中使用foreach
循环进行迭代,并执行以下操作:
foreach (Apple apple in consumables)
{
renderer.DrawApple(apple);
}
但是当数组中有不同的对象,如Apple
和SegmentRemover
时(这是可能的,因为它们继承自Consumable
类),编译器会迭代SegmentRemover
也是如此,我收到了无效的强制转换异常。
我想,因为我在foreach
循环中声明我只想迭代Apple
个对象,它应该可以工作。
有没有简单的方法来解决这个问题?最好不要使用var
或typeof
之类的内容,因为我还不允许使用这些内容。
答案 0 :(得分:5)
您真正想要的只是那些“可投递”到Apple
类型的项目。对于该用途OfType<Apple>
(使用linq):
foreach (Apple apple in consumables.OfType<Apple>())
{
renderer.DrawApple(apple);
}
非linq解决方案几乎可以使用as
operator:
foreach(var item in consumbles)
{
var apple = item as Apple;
if(apple != null)
{
renderer.DrawApple(apple);
}
}
然而IMO如果所有这些项目都放在同一个列表中,并且它们都已经从Consumble
继承,那么使用多态性的更好的设计就是为每种类型的Consumable
定义@dasblinkenlight建议使用draw
方法。并针对每种类型进行特定实施。对于SegmentRemover
,它可能是一个空实现,而Apple
可能会调用renderer
。
答案 1 :(得分:4)
你可以翻转逻辑,让每个耗材在渲染器中绘制自己:
interface IConsumable {
void draw(Renderer renderer);
}
class Apple : IConsumable {
void draw(Renderer renderer) {
renderer.DrawApple(this);
}
}
class SegmentRemover : IConsumable {
void draw(Renderer renderer) {
renderer.DrawSegmentRemover(this);
}
}
现在你的循环可以这样:
foreach (IConsumable consumable in consumables) {
consumable.Draw(renderer);
}
这样,您在Draw
的每个实例上以多态方式调用IConsumable
,因此执行的代码在运行时由实现IConsumable
接口的实际类决定。
答案 2 :(得分:-2)
您的耗材是集合,您是否尝试使用存储集合的对象实例访问集合?如是: 尝试:
HdfsClient