title: Generic constraints, where T : struct and where T : class
body: <p>I would like to differentiate between following cases:</p>
  
  <ol>
  <li>A plain value type (e.g. <code>int</code>)</li>
  <li>A nullable value type (e.g. <code>int?</code>)</li>
  <li>A reference type (e.g. <code>string</code>) - optionally, I would not care if this mapped to (1) or (2) above</li>
  </ol>
  
  <p>I have come up with the following code, which works fine for cases (1) and (2):</p>
  
  <pre><code>static void Foo&lt;T&gt;(T a) where T : struct { } // 1
  
  static void Foo&lt;T&gt;(T? a) where T : struct { } // 2
  </code></pre>
  
  <p>However, if I try to detect case (3) like this, it does not compile:</p>
  
  <pre><code>static void Foo&lt;T&gt;(T a) where T : class { } // 3
  </code></pre>
  
  <p>The error message is <em>Type 'X' already defines a member called 'Foo' with the same parameter types</em>. Well, somehow I cannot make a difference between <code>where T : struct</code> and <code>where T : class</code>.</p>
  
  <p>If I remove the third function (3), the following code does not compile either:</p>
  
  <pre><code>int x = 1;
  int? y = 2;
  string z = "a";
  
  Foo (x); // OK, calls (1)
  Foo (y); // OK, calls (2)
  Foo (z); // error: the type 'string' must be a non-nullable value type ...
  </code></pre>
  
  <p>How can I get <code>Foo(z)</code> to compile, mapping it to one of the above functions (or a third one with another constraint, which I have not thought of)?</p>