다음은 복합 패턴을 사용하기위한 첫 번째 시도입니다.복합 반복 실패 (.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
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
철자가 틀린 이름입니다. 죄송합니다. 내가 통과의 깊이를 제한하고있는 곳을 보지 않고 있습니다. 모든 진부한 것들을 얻기 위해 어떻게 수정합니까? 건배 – Berryl
@ Berryl : 네 말이 맞았다. 나는 편집을했다. – Ani