title: Union or Variant type static dispatch
body: <p>I have a function which takes a number of arguments, each of which may be one of a set of types.</p>
  
  <p>I can handle this dynamically and throw a type error if it fails, as in the code snippet directly below but I would much rather catch these type errors at compile time.</p>
  
  <pre class="lang-vb prettyprint-override"><code>Function specializingFunction(a) As String
      Select Case a.GetType
          Case GetType(Integer)
              Return "INT"
          Case GetType(Boolean)
              Return "BOOL"
          Case Else
              Return "__UNKNOWN__"  ' or throw an exception
      End Select
  End Function
  
  Sub mayFail(a1, a2, a3, a4)
      Console.WriteLine(specializingFunction(a1))
      Console.WriteLine(specializingFunction(a2))
      Console.WriteLine(specializingFunction(a3))
      Console.WriteLine(specializingFunction(a4))
  End Sub
  </code></pre>
  
  <p>I had hoped to solve this problem using dotNET generics, see the final code example in this question.</p>
  
  <p>I am happy to use either:
     1. an open solution - client code may add further type specializations as in the c++ code below
     2. a closed solution - a fixed set of allowed types, as could be acheived with algebraic data types in (e.g.) Haskell or boost::variant in C++</p>
  
  <p>...but I would be interested to hear answers for both.</p>
  
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;string&gt;
  #include &lt;iostream&gt;
  
  using namespace std;
  
  string specializedFunction(bool x)
  {
     return string("BOOL");
  }
  
  
  std::string specializedFunction(int x)
  {
     return string("INT");
  }
  
  template&lt;typename T1, typename T2, typename T3, typename T4&gt;
  void correctlyResolves(T1 a1, T2 a2, T3 a3, T4 a4)
  {
     cout &lt;&lt; specializedFunction(a1) &lt;&lt; "\n";
     cout &lt;&lt; specializedFunction(a2) &lt;&lt; "\n";
     cout &lt;&lt; specializedFunction(a3) &lt;&lt; "\n";
     cout &lt;&lt; specializedFunction(a4) &lt;&lt; "\n";
  }
  
  
  int main()
  {
      correctlyResolves(1, true, 3, 4);
      return 0;
  }
  </code></pre>
  
  <p>Haskell example</p>
  
  <pre><code>data X = XInt Int | XBool Bool
  
  descriminator :: X -&gt; String  
  descriminator (XInt  a) = "INT: " ++ show a
  descriminator (XBool a) = "BOOL: " ++ show a
  
  
  lottaArgs :: X -&gt; X -&gt; X -&gt; X -&gt; IO ()
  lottaArgs a b c d = do 
                       putStrLn $ descriminator a
                       putStrLn $ descriminator b
                       putStrLn $ descriminator c
                       putStrLn $ descriminator d
  
  main = lottaArgs (XInt 1) (XBool False) (XInt 2) (XInt 3)
  </code></pre>
  
  <p>The solution that I tried is the one below, however is appears VB attempts to instantiate the function in its generic form (without knowing the types T1 - T4). VB therefore gives the errors of the form "Value Type 'T1' cannot be converted to 'Integer'".</p>
  
  <pre class="lang-vb prettyprint-override"><code>Function specializedFunction(a As Boolean) As String
      Return "BOOL"
  End Function
  
  Function specializedFunction(a As Integer) As String
      Return "INT"
  End Function
  
  Sub failsHorribly(Of T1, T2, T3, T4)(a1 As T1, a2 As T2, a3 As T3, a4 As T4)
     Console.WriteLine(specializedFunction(a1))
     Console.WriteLine(specializedFunction(a2))
     Console.WriteLine(specializedFunction(a3))
     Console.WriteLine(specializedFunction(a4))
  End Sub
  
  Sub Main()
     failsHorribly(1, True, 3, 4)
  End Sub
  </code></pre>
  
  <p>How best can I solve this sort of design problem in VB? Is there any appropriate statically-verified union or variant type?</p>
  
  <p>I guess I could create a custom type with an <code>Object</code> member which can only be constructed with one of the allowed types, but this does not seem very elegant, there must be a better way.</p>
  
  <h2>Edit: Solution</h2>
  
  <p>See my answer below for an implementation of a wrapper-object based solution</p>