public interface IComponent
{
string Name { get; }
}
public interface IComposite : IComponent
{
void AddRange(IEnumerable<IComponent> components);
}
public interface ILeaf : IComponent
{
string Content { get; }
string Parent { get; }
}
public class Composite : IComposite
{
// return an iterator?
private readonly List<IComponent> _children = new List<IComponent>();
public Composite(string name)
{
Name = name;
}
public string Name { get; }
public void AddRange(IEnumerable<IComponent> components)
{
_children.AddRange(components);
}
}
public class Leaf : ILeaf
{
public string Name { get; }
public string Content { get; }
public string Parent { get; }
public Leaf(string name, string content, string parent)
{
Name = name;
Content = content;
Parent = parent;
}
}
我已經填充了複合從XML文件如下
var collection = XElement.Load(@"C:\somexml.xml");
var composite = CreateComposite(collection);
其中
實現的複合圖案組合模式的葉節點public IComponent CreateComposite(XElement element)
{
if (!element.HasElements)
return new Leaf(element.Name.LocalName, element.Value, element.Parent.Name.LocalName);
var composite = new Composite(element.Name.LocalName);
composite.AddRange(element.Elements().Select(CreateComposite));
return composite;
}
這會像預期的那樣填充我的複合材料 - 非常棒!不過,我現在希望我的組合通過IEnumerable的實現返回一個迭代器。於是我通過組件的頂層試過這種
public class Composite : IComposite, IEnumerable<IComponent>
{
// return an iterator?
private readonly List<IComponent> _children = new List<IComponent>();
public Composite(string name)
{
Name = name;
}
public string Name { get; }
public void AddRange(IEnumerable<IComponent> components)
{
_children.AddRange(components);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public IEnumerator<IComponent> GetEnumerator()
{
foreach (var child in _children)
{
yield return child;
}
}
}
但這只是迭代,即,將不返回嵌套在_children
任何組件。我如何更新這個遞歸遍歷所有組件?
所以我改變了我的接口,使得'IComponent'實現IEnumerable',然後在沒有強制轉換的情況下使用你的代碼,在'Leaf'中使用'yield break'來實現'GetEnumerator'(見[here](http:/ /stackoverflow.com/questions/1714351/return-an-empty-ienumerator))。這爲我提供了深度優先遞歸 - 非常棒! –