嗨,我现在遇到了一些问题,我目前有一个班级“船”,其子类为“播放器”& “敌人”他们都在名单“船”中
我要做的是从“船舶”列表中提取“Player thePlayer” 我已经尝试过使用List.Find()而没有任何成功,是不是我使用它错了或是处理这个问题的错误方法?
for (int i = 0; i < HomingBullets.Count; i++)
{
HomingBullet h = HomingBullets.ElementAt(i);
Player thePlayer = ??? List.Find ???
h.Update(gameTime, thePlayer.position);
}
h.Update接受两个参数(gameTime&amp; Vector2) 我正在尝试使用上面的代码提取Vector2。
请记住,自今年年初以来我只使用过C#,尽管我有多年的各种语言编程经验。
答案 0 :(得分:3)
您可以使用LINQ的OfType<>运算符仅从列表或IEnumerable中返回特定类型的对象。例如。你可以写
Ships.OfType<Player>()
仅返回Player类型的实例。
这是一种非常低效的搜索方式,因为它遍历所有Ships。我怀疑玩家船只只占总船只的很小一部分。最好保留一个引用Ship集合中的Ship实例的Player船的单独列表。
答案 1 :(得分:1)
list.Find(sh => sh is Player);
这相当于创建一个方法:
bool IsPlayer(Ship sh)
{
return sh is Player;
}
然后迭代直到该方法在每个项目上调用时返回true(如果没有找到这样的项目,则返回null。
答案 2 :(得分:1)
您可以使用is
关键字测试对象是否是给定类的实例:x is Player
对于您的播放器对象应为true,对于Enemy
的实例为false列表。
在isPlayer
课程中定义Ship
方法(Player
和Enemy
中的定义返回不同的值)可能是更好的方式,或者 - 如果在事实上,总有一个Player
对象 - 将其保存在其他地方,而不是在列表中反复查找。
答案 3 :(得分:1)
可以说,比任何一个更好的解决方案是使用GameComponent
(或DrawableGameComponent
)和GameServices
。这将允许您能够抓取Player
对象,而无需始终对其进行硬性引用。相反,您只需要引用Game
对象。
其他参考
答案 4 :(得分:0)
最简单的解决方案是向Ship
类添加readonly属性:
class Ship
{
public abstract bool IsPlayer { get; }
}
class Player : Ship
{
public override bool IsPlayer { get { return true; } }
}
class Enemy : Ship
{
public override bool IsPlayer { get { return false; } }
}
然后你可以做
var thePlayer = (Player)shipList.Find(s => s.IsPlayer);
如果你可以将该对象用作一般Player
而不是更具体的Ship
,我可能会转向Player
(我假设shipList
是一个List<Ship>
,对吗?)。
其他解决方案(例如使用is
关键字或等效的LINQ shipList.OfType<Player>().Single()
也可以正常工作,但检查运行时类型将比IsPlayer
属性检查慢得多