title: Discriminated union in C#
body: <p>[Note: This question had the original title "<strong>C (ish) style union in C#</strong>"
  but as Jeff's comment informed me, apparently this structure is called a 'discriminated union']</p>
  
  <p>Excuse the verbosity of this question.</p>
  
  <p>There are a couple of similar sounding questions to mine already in SO but they seem to concentrate on the memory saving benefits of the union or using it for interop.
  <a href="https://stackoverflow.com/questions/126781/c-union-in-c">Here is an example of such a question</a>.</p>
  
  <p>My desire to have a union type thing is somewhat different.</p>
  
  <p>I am writing some code at the moment which generates objects that look a bit like this</p>
  
  <pre><code>public class ValueWrapper
  {
      public DateTime ValueCreationDate;
      // ... other meta data about the value
  
      public object ValueA;
      public object ValueB;
  }
  </code></pre>
  
  <p>Pretty complicated stuff I think you will agree.  The thing is that <code>ValueA</code> can only be of a few certain types (let's say <code>string</code>, <code>int</code> and <code>Foo</code> (which is a class) and <code>ValueB</code> can be another small set of types.  I don't like treating these values as objects (I want the warm snugly feeling of coding with a bit of type safety).  </p>
  
  <p>So I thought about writing a trivial little wrapper class to express the fact that ValueA logically is a reference to a particular type.  I called the class <code>Union</code> because what I am trying to achieve reminded me of the union concept in C.</p>
  
  <pre><code>public class Union&lt;A, B, C&gt;
  {
      private readonly Type type; 
      public readonly A a;
      public readonly B b;
      public readonly C c;
  
      public A A{get {return a;}}
      public B B{get {return b;}}
      public C C{get {return c;}}
  
      public Union(A a)
      {
          type = typeof(A);
          this.a = a;
      }
  
      public Union(B b)
      {
          type = typeof(B);
          this.b = b;
      }
  
      public Union(C c)
      {
          type = typeof(C);
          this.c = c;
      }
  
      /// &lt;summary&gt;
      /// Returns true if the union contains a value of type T
      /// &lt;/summary&gt;
      /// &lt;remarks&gt;The type of T must exactly match the type&lt;/remarks&gt;
      public bool Is&lt;T&gt;()
      {
          return typeof(T) == type;
      }
  
      /// &lt;summary&gt;
      /// Returns the union value cast to the given type.
      /// &lt;/summary&gt;
      /// &lt;remarks&gt;If the type of T does not exactly match either X or Y, then the value &lt;c&gt;default(T)&lt;/c&gt; is returned.&lt;/remarks&gt;
      public T As&lt;T&gt;()
      {
          if(Is&lt;A&gt;())
          {
              return (T)(object)a;    // Is this boxing and unboxing unavoidable if I want the union to hold value types and reference types? 
              //return (T)x;          // This will not compile: Error = "Cannot cast expression of type 'X' to 'T'."
          }
  
          if(Is&lt;B&gt;())
          {
              return (T)(object)b; 
          }
  
          if(Is&lt;C&gt;())
          {
              return (T)(object)c; 
          }
  
          return default(T);
      }
  }
  </code></pre>
  
  <p>Using this class ValueWrapper now looks like this</p>
  
  <pre><code>public class ValueWrapper2
  {
      public DateTime ValueCreationDate;
      public  Union&lt;int, string, Foo&gt; ValueA;
      public  Union&lt;double, Bar, Foo&gt; ValueB;
  }
  </code></pre>
  
  <p>which is something like what I wanted to achieve but I am missing one fairly crucial element - that is compiler enforced type checking when calling the Is and As functions as the following code demonstrates</p>
  
  <pre><code>    public void DoSomething()
      {
          if(ValueA.Is&lt;string&gt;())
          {
              var s = ValueA.As&lt;string&gt;();
              // .... do somethng
          }
  
          if(ValueA.Is&lt;char&gt;()) // I would really like this to be a compile error
          {
              char c = ValueA.As&lt;char&gt;();
          }
      }
  </code></pre>
  
  <p>IMO It is not valid to ask ValueA if it is a <code>char</code> since its definition clearly says it is not - this is a programming error and I would like the compiler to pick up on this.  [Also if I could get this correct then (hopefully) I would get intellisense too - which would be a boon.]  </p>
  
  <p>In order to achieve this I would want to tell the compiler that the type <code>T</code> can be one of A, B or C</p>
  
  <pre><code>    public bool Is&lt;T&gt;() where T : A 
                             or T : B // Yes I know this is not legal!
                             or T : C 
      {
          return typeof(T) == type;
      } 
  </code></pre>
  
  <p>Does anyone have any idea if what I want to achieve is possible?  Or am I just plain stupid for writing this class in the first place?</p>
  
  <p>Thanks in advance.</p>