[英]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.