我正在制作一款游戏,可以专门针对每个暴徒的肢体,所以你可以瞄准头部,腿部......
我有这个构造函数:
public Humanoid(Race race, Gender gender, string firstname, string lastname = null)
{
this.Legs = new List<Leg> { new Leg(), new Leg() };
this.Torso = new Torso();
this.Arms = new List<Arm> { new Arm(), new Arm() };
this.Heads = new List<Head>
{
new Head
{
Ears = new List<Ear> { new Ear(), new Ear() },
Eyes = new List<Eye> { new Eye(), new Eye() }
}
};
}
所有这些肢体都继承自界面ILimb
。
能够遍历所有肢体的最佳方法是什么,包括孩子(如果适用)?
我可以添加protected List<ILimb> { get; set; }
,然后添加每个,但这是多余的。
有任何改进的想法或建议吗?
答案 0 :(得分:3)
最好的方法是改为使用这种结构:
public Humanoid(Race race, Gender gender, string firstname, string lastname = null)
{
this.Limbs = new List<ILimb>();
this.Limbs.Add(new Legs() { Limbs = new List<Limb>() { new Leg(), new Leg() });
this.Limbs.Add(new Torso());
this.Limbs.Add(new Arms() { Limbs = new List<Limb>() { new Arm(), new Arm() });
this.Limbs.Add(new Heads() { Limbs = new List<Limb>() { new Head() { Limbs = new List<Limb>() .... , ... });
}
你可以整理代码,但基本上它应该有一个肢体的集合,肢体应该有四肢的集合,以便你可以有头&gt;耳朵&gt;耳朵或你想要的任何层次结构。
然后在你的ILimb界面中,给它一个Limbs属性
public interface ILimb
{
List<ILimb> Limbs { get; set; }
List<ILimb> GetAllLimbs { get; }
}
使用此方法创建一个抽象基类Limb:
public virtual GetAllLimbs()
{
// pseudocode: something like this (basically recurse through the children)
return this.Limbs().foreach (c => c.GetAllLimbs()).union(this.Limbs());
}
然后它可以轻松地爬下层次结构并检索每个肢体。
所以你可以做到
myHumanoid.GetAllLimbs().Where(c => c is Arm).TakeDamage(5);
例如。
答案 1 :(得分:1)
您有所有对象的自定义模型,除了一个...模型的自定义集合。 List<T>
是一个良好的开端,但它没有您正在寻找的功能。您尝试投入Humanoid
的功能,但并不属于那里。
实施以下内容:
public class LimbList<T> : IList<T> where T : ILimb
{
// implement IList<T> here
}
在这里,您将包括四肢集合的业务逻辑。例如:
Arm
个对象,则在使用.Add()
对象调用Arm
时抛出异常。Torso
对象,则在使用.Add()
对象调用Torso
时抛出异常。 Humanoid
将拥有LimbList<ILimb>
属性:
public Humanoid(Race race, Gender gender, string firstname, string lastname = null)
{
this.Limbs.Add(new Leg());
this.Limbs.Add(new Leg());
this.Limbs.Add(new Torso());
this.Limbs.Add(new Arm());
this.Limbs.Add(new Arm());
this.Limbs.Add(new Head
{
// as an added exercise, how would you extend this concept to the Head object?
});
}
你可以轻松地遍历该列表:
foreach (var limb in this.Limbs)
基本上,这里的要点是对象集合本身就是一个对象,其自定义逻辑与任何其他对象一样。将对象逻辑放在对象中,将集合逻辑放入集合中。没有规则说您必须仅使用框架中的内置集合。
答案 2 :(得分:0)
给定legs
列表和arms
列表,您可以执行以下操作:
IEnumerable<ILimb> limbs = ((IEnumerable<ILimb>)arms).Concat(legs);
然后迭代它:
foreach (var limb in limbs)
{
// limb is an ILimb and you can access anything in that interface
// for each limb
}
另一种方法是你可以像Humanoid
这样添加一个方法:
public IEnumerable<ILimb> GetLimbs()
{
foreach (var a in Arms)
{
yield return a;
}
foreach (var l in Legs)
{
yield return l;
}
}
然后你可以这样做:
foreach(var limb in someHumanoid.GetLimbs())
{
}