[英]Looping through a parent / Child structure
我正在开发一款游戏,可以专门针对每个暴民的四肢,因此您可以瞄准头部,腿部...
我有这个构造函数:
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
都从接口ILimb
继承。
能够绕过包括儿童在内的所有肢体的最佳方法是什么(如果适用)?
我可以添加一个protected List<ILimb> { get; set; }
protected List<ILimb> { get; set; }
protected List<ILimb> { get; set; }
,然后添加每个,但这是多余的。
有任何改进的想法或建议吗?
最好的方法是改用以下结构:
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>() .... , ... });
}
您可以整理代码,但基本上它应该具有四肢的集合,并且四肢应该具有四肢的集合,以便您可以具有Head> Ears> Ear或您想要的任何层次结构。
然后在您的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);
例如。
您为所有对象都拥有定制模型,除了一个...定制的模型集合 。 List<T>
是一个好的开始,但是它没有您要寻找的功能。 您尝试将功能添加到Humanoid
但实际上并不属于其中。
实现这样的事情:
public class LimbList<T> : IList<T> where T : ILimb
{
// implement IList<T> here
}
在这里,您将包括用于收集肢体的业务逻辑。 例如:
Arm
对象,则使用Arm
对象调用.Add()
时将引发异常。 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)
从本质上讲,这里的重点是对象集合本身就是一个对象,具有与其他任何对象一样的自定义逻辑。 将对象逻辑放入对象中,将集合逻辑放入集合中。 没有规则说您只能使用框架中的内置集合。
给定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())
{
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.