下面是使用複合模式的第一次嘗試。複合迭代失敗(.net)
它的工作原理是,我可以隨意嵌套並獲得Duration屬性的正確結果,並且是合成的焦點。但在一個編碼問題迭代超過所需輸出複合的ToString()孩子失敗:
System.InvalidOperationException : Collection was modified; enumeration operation may not execute.
的是在這個posting GetDescendents一些擴展方法,包括使用堆棧,以避免一個花費遞歸和嵌套迭代器。
我想了解的圖案最好先的,所以我有幾個問題在這裏:
- 我怎樣才能改變現有的重複代碼,以防止這種錯誤?我知道如何將它轉換爲Linq等價物,但我想把它作爲循環直到我明白它有什麼問題。
- 在Composite中提供Count屬性還是以某種方式緩存迭代後的計數是典型的?
- 在您不需要專門收藏的一般情況下,您通常會將您的Children屬性設置爲IEnumerable,IList還是List?
任何工作(非trival).net代碼示例的良好鏈接也將非常感激。
乾杯,
Berryl
CODE
public interface IComponent {
void Adopt(IComponent node);
void Orphan(IComponent node);
TimeSpan Duration { get; }
IEnumerable<IComponent> Children { get; }
}
public class Allocation : Entity, IAllocationNode {
public void Adopt(IAllocationNode node) { throw new InvalidOperationException(_getExceptionMessage("Adopt", this, node)); }
public void Orphan(IAllocationNode node) { throw new InvalidOperationException(_getExceptionMessage("Orphan", this, node)); }
public IEnumerable<IAllocationNode> Allocations { get { return Enumerable.Empty<IAllocationNode>(); } }
public virtual TimeSpan Duration { get; set; }
}
class MyCompositeClass : IAllocationNode {
public MyCompositeClass() { _children = new List<IAllocationNode>(); }
public void Adopt(IAllocationNode node) { _children.Add(node); }
public void Orphan(IAllocationNode node) { _children.Remove(node); }
public TimeSpan Duration {
get {
return _children.Aggregate(TimeSpan.Zero, (current, child) => current + child.Duration);
}
}
public IEnumerable<IAllocationNode> Children {
get {
var result = _children;
foreach (var child in _children) {
var childOnes = child.Children;
foreach (var node in childOnes) {
result.Add(node);
}
}
return result;
}
}
private readonly IList<IAllocationNode> _children;
#endregion
public override string ToString() {
var count = Children.Count();
var hours = Duration.TotalHours.ToString("F2");
return string.Format("{0} allocations for {1} hours", count, hours);
}
}
@Ari。是的,這解決了它。我沒有看到我限制遍歷的深度 - 你將如何修改這個以獲得所有的後代? – Berryl 2011-03-20 15:13:52
拼寫錯了你的名字,對不起。我沒有看到我在限制遍歷的深度 - 你會如何修改這個以獲得所有的後代?乾杯 – Berryl 2011-03-20 15:20:22
@Berryl:你說得對;我已經進行了編輯。 – Ani 2011-03-20 15:21:38