1

I'm trying to setup a recursive logic using Yield. Here is my scenario: I have a collection of NodeviewModel items, and each NodeviewModel item can have multiple children of type NodeViewModel item. The depth of the graph could be 'n'. Basically, I'm getting NodeviewModel item and converting into a different form.

Here is the code:

public class CompositeContentBuilder
    {
        private readonly IContentFactory _contentFactory;

        public CompositeContentBuilder(IContentFactory contentFactory)
        {
            _contentFactory = contentFactory;
        }

        public IEnumerable<IContentViewModel> BuildFrom(IEnumerable<INodeViewModel> nodes)
        {

            if (nodes.Count() == 1)
                yield return BuildFrom(nodes.First());

            foreach (var nodeViewModel in nodes)
            {
                yield return BuildFrom(nodeViewModel);
                foreach (var viewModel in nodeViewModel.Children)
                {
                    yield return BuildFrom(viewModel);
                }

                //How do I return children.children...and so on?
            }
        }

        private IContentViewModel BuildFrom(INodeViewModel node)
        {
            var content = _contentFactory.Create(node);
            content.Initialise();
            return content;
        }
    }

How will I convert children.children and so on? Could you please help?

4

2 に答える 2

1
public IEnumerable<IContentViewModel> BuildFrom(IEnumerable<NodeViewModel> nodes)
{
    foreach (var nodeViewModel in nodes)
    {
        yield return BuildFrom(nodeViewModel);
        foreach(var child in BuildFrom(nodeViewModel.Children)) // recursive call
           yield return child; 
    }
}
于 2013-02-19T15:20:26.600 に答える
1

a を使用して、Stack実際に再帰を使用せずに再帰動作を模倣できます。

public IEnumerable<IContentViewModel> BuildFrom(IEnumerable<NodeViewModel> nodes)
{
    Stack<NodeViewModel> stack = new Stack<NodeViewModel>(nodes);

    while (stack.Any())
    {
        var next = stack.Pop();
        yield return BuildFrom(next);
        foreach (var child in next.Children)
        {
            stack.Push(child);
        }
    }
}

また、単一のノードを受け入れるメソッドの名前を変更することをお勧めしBuildFromます。これは、そうでない場合にメソッドが再帰的に見えるようにして混乱を招くためです。

于 2013-02-19T15:27:45.757 に答える