I find recursive expression to be really useful. They are particularly handy when dealing with parent child relationships. As a demonstration, see a potential method for generating a site map below:
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace SiteMapDemo
7 {
8 class MenuItem
9 {
10 public Guid ID { get; set; }
11 public Guid? ParentID { get; set; }
12 public string Name { get; set; }
13 public string Path { get; set; }
14 public int Rank { get; set; }
15 }
16 class Program
17 {
18 static void Main(string[] args)
19 {
20 List<MenuItem> menu = new List<MenuItem>(new[]{
21 new MenuItem{ID = Guid.NewGuid(), Name = "First", ParentID=null, Path="/", Rank=0},
22 new MenuItem{ID = Guid.NewGuid(), Name = "Second", ParentID=null, Path="/second.aspx",Rank=1},
23 });
24 menu.AddRange(new[] {
25 new MenuItem{ID = Guid.NewGuid(), Name = "FirstSub", ParentID=menu[0].ID, Path="/firstsub.aspx",Rank=0},
26 new MenuItem{ID = Guid.NewGuid(), Name = "SecondSub", ParentID=menu[0].ID, Path="/secondsub.aspx",Rank=1},
27 });
28 Func<List<MenuItem>, Guid?, string> renderMenu = null;
29 renderMenu = (menus, Parent) =>
30 {
31 var sub = menus.Where(m => m.ParentID == Parent).OrderBy(s => s.Rank).ToList();
32 if (sub.Count > 0)
33 {
34 StringBuilder sb = new StringBuilder();
35 sub.ForEach(s => { sb.Append(String.Format("<li><a href=\"{0}\">{1}</a>{2}</li>", s.Path, s.Name, renderMenu(menus, s.ID))); });
36 return sb.ToString();
37 }
38 return "";
39 };
40 Console.Write(renderMenu(menu, null));
41 Console.ReadLine();
42 }
43 }
44 }
<li><a href="http://www.charlesrcook.com/">First</a></li><li><a href="http://www.charlesrcook.com/firstsub.aspx">FirstSub</a></li><li><a href="/secondsub.aspx">SecondSub</a></li><li><a href="http://www.charlesrcook.com/second.aspx">Second</a></li>