title: Does "Select New" in linq trigger an evaluation / load?
body: <p>I'm currently trying to create a class which implements <code>IEnumerable&lt;T&gt;</code> in order to construct a Hierarchy from a flat list of objects which have references to each other through a ParentId property. I'd like to write a fluent interface for this so I can do something like this</p>
  
  <pre><code>IEnumerable&lt;Tab&gt; tabs = GetTabs();
  
  IEnumerable&lt;TabNode&gt; tabNodes = tabs.AsHierarchy().WithStartLevel(2).WithMaxDepth(5);
  </code></pre>
  
  <p>So, about the yield statement, I wonder whether I could do something like this within my <code>NodeHierarchy : IEnumerable&lt;TabNode&gt;</code> class:</p>
  
  <pre><code>private IEnumerable&lt;TabNode&gt; _nodes;
  
  public NodeHierarchy(IEnumerable&lt;Tab&gt; tabs)
  {
      _nodes = CreateHierarchy(tabs);
  }
  
  public IEnumerable&lt;TabNode&gt; CreateHierarchy(IEnumerable&lt;Tab&gt; tabs)
  {
      /* About this block: I'm trying to find the top level 
      nodes of the first tab collection, maybe this is done poorly? */
      var tabIds = tabs.Select(t =&gt; t.TabID);
      IEnumerable&lt;TabNode&gt; nodes = from tab in tabs
                               where !tabIds.Contains(tab.ParentId)
                                   select new TabNode {
                                              Tab = node,
                                              ChildNodes = CreateHierarchy(tabs, node.TabID, 1),
                                              Depth = 1 };
      return nodes;
  }
  </code></pre>
  
  <p>or whether I would have to do something like this:</p>
  
  <pre><code>private IEnumerable&lt;TabNode&gt; _nodes;
  
  public NodeHierarchy(IEnumerable&lt;Tab&gt; tabs)
  {
      _nodes = CreateHierarchy(tabs);
  }
  
  public IEnumerable&lt;TabNode&gt; CreateHierarchy(IEnumerable&lt;Tab&gt; tabs)
  {
  var tabIds = tabs.Select(t =&gt; t.TabID);
  IEnumerable&lt;Tab&gt; startingNodes = from tab in tabs
                                   where !tabIds.Contains(tab.ParentId)
                                   select tab;
  
  foreach(Tab node in startingNodes)
  {
      yield return
      new TabNode()
          {
          Tab = node,
          ChildNodes = CreateHierarchy(tabs, node.TabID, 1),
          Depth = 1
      };
  }
  </code></pre>