I've implemented the composite pattern as follows
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;
}
}
I've populated the composite from an xml file as follows
var collection = XElement.Load(@"C:\somexml.xml");
var composite = CreateComposite(collection);
where
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;
}
This populates my composite as expected - great! However, I'd now like my composite to return an iterator via the implementation of IEnumerable. So I tried this
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;
}
}
}
But this only iterates through the top level of components, i.e., any components nested within _children
are not returned. How do I update this to recursively iterate through all components?