c# - Implementing IEnumerable for Leaf Nodes of Composite Pattern -
i've implemented composite pattern 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 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 composite xml file 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 composite expected - great! however, i'd composite return iterator via implementation of ienumerable. tried this
public class composite : icomposite, ienumerable<icomponent> { // return 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 iterates through top level of components, i.e., components nested within _children
not returned. how update recursively iterate through components?
you can iterate recursively (it iteration in depth-first manner):
public interface icomposite : icomponent, ienumerable<icomponent> { void addrange(ienumerable<icomponent> components); } public ienumerator<icomponent> getenumerator() { foreach (var child in _children) { yield return child; var composite = child icomposite; if (composite != null) { foreach (var sub in composite) { yield return sub; } } } }
if want avoid cast icomposite
- need redesign interfaces , make composite
hold list of icomposite
s instead of components. ileft
become icomposite
dummy implementation.
Comments
Post a Comment