title: Switch statement with non-constant-expression - Extends C#/IDE ability
body: <p>Before you start criticizing and pointing me §8.7.2 of <a href="http://www.microsoft.com/download/en/details.aspx?id=7029" rel="noreferrer">C# specification</a>, read carefully :)</p>
  
  <p>We all know how switch looks like in C#. Ok so consider the class <code>MainWindow</code> with "nasty" <i>Bar</i> method</p>
  
  <pre class="lang-cs prettyprint-override"><code>static int barCounter = 0;
  public static int Bar()
  {
      return ++barCounter;
  }
  </code></pre>
  
  <p>Somewhere in this class we have code like this</p>
  
  <pre class="lang-cs prettyprint-override"><code>Action switchCode = () =&gt;
  {
      switch (Bar())
      {
          case 1:
              Console.WriteLine("First");
              break;
          case 2:
              Console.WriteLine("Second");
              break;
      }
  };
  
  switchCode();
  
  switchCode();
  </code></pre>
  
  <p>In the console window we will see </p>
  
  <pre><code>First
  Second
  </code></pre>
  
  <p>Using Expressions in C# we could do the same – writing much same code</p>
  
  <pre class="lang-cs prettyprint-override"><code>var switchValue = Expression.Call(typeof(MainWindow).GetMethod("Bar"));
  
  var WriteLine = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) });
  
  var @switch = Expression.Switch(switchValue,
      Expression.SwitchCase(
          Expression.Call(WriteLine, Expression.Constant("First")),
          Expression.Constant(1)
          ),
      Expression.SwitchCase(
          Expression.Call(WriteLine, Expression.Constant("Second")),
          Expression.Constant(2)
          )
      );
  
  Action switchCode = Expression.Lambda&lt;Action&gt;(@switch).Compile();
  
  switchCode();
  
  switchCode();
  </code></pre>
  
  <p>In DebugView we could see "code behind" this expression</p>
  
  <pre><code>.Switch (.Call WpfApplication1.MainWindow.Bar()) {
  .Case (1):
          .Call System.Console.WriteLine("First")
  .Case (2):
          .Call System.Console.WriteLine("Second")
  }
  </code></pre>
  
  <p>Ehmm, what if we use <code>Expression.Call</code> instead <code>Expression.Constant</code>?</p>
  
  <pre class="lang-cs prettyprint-override"><code>public static bool foo1() { return false; }
  
  public static bool foo2() { return true; }
  
  // .....
  
  var foo1 = Ex.Call(typeof(MainWindow).GetMethod("foo1"));
  var foo2 = Ex.Call(typeof(MainWindow).GetMethod("foo2"));
  var switchValue = Ex.Call(typeof(MainWindow).GetMethod("Bar"));
  
  var WriteLine = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) });
  
  var @switch = Ex.Switch(Ex.Constant(true),
      Ex.SwitchCase(
          Ex.Call(WriteLine, Ex.Constant("First")),
          foo1
          ),
      Ex.SwitchCase(
          Ex.Call(WriteLine, Ex.Constant("OK!")),
          Ex.Equal(switchValue, Ex.Constant(2))
          ),
      Ex.SwitchCase(
          Ex.Call(WriteLine, Ex.Constant("Second")),
          foo2
          )
      );
  
  Action switchCode = Ex.Lambda&lt;Action&gt;(@switch).Compile();
  
  switchCode();
  
  switchCode();
  </code></pre>
  
  <p>Console window shows, as we expected</p>
  
  <pre><code>Second
  OK!
  </code></pre>
  
  <p>And DebugView</p>
  
  <pre><code>.Switch (True) {
  .Case (.Call WpfApplication1.MainWindow.foo1()):
          .Call System.Console.WriteLine("First")
  .Case (.Call WpfApplication1.MainWindow.Bar() == 2):
          .Call System.Console.WriteLine("OK!")
  .Case (.Call WpfApplication1.MainWindow.foo2()):
          .Call System.Console.WriteLine("Second")
  }
  </code></pre>
  
  <p>So it is possible to use non-constant expression in case-statement :)</p>
  
  <p>Ok, I known this is little ‘messy’ code. But here comes my question (finally :P):<br />
  <b>Is there any way to extends functionality of IDE/VisualStudio/compiler to do this, but with more elegant code?</b><br />
  Something like this</p>
  
  <pre class="lang-cs prettyprint-override"><code>switch (true)
  {
      case foo1():
          Console.WriteLine("First");
          break;
      case Bar() == 2:
          Console.WriteLine("OK!");
          break;
      case foo2():
          Console.WriteLine("Second");
          break;
  }
  </code></pre>
  
  <p>I know this will be some extension and code will be not the same (not the same performance). But I wonder if this is even possible to "change" code on-the-fly – like anonymous function or yield return is transform to nested class.</p>
  
  <p>I hope someone goes through the above text and leave some clue.</p>