簡體   English   中英

遍歷父/子結構

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

在這里,您將包括用於收集肢體的業務邏輯。 例如:

  • 如果支持集合中已經有2個Arm對象,則使用Arm對象調用.Add()時將引發異常。
  • 如果已經有1個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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM