title: Lazy<T> implementation and .NET generics
body: <p>I was looking for ways to do lazy initialization and found <a href="http://msdn.microsoft.com/en-us/library/dd642331.aspx" rel="noreferrer"><code>Lazy&lt;T&gt;</code></a> which is included in .NET 4.</p>
  
  <p>I was thinking of rolling my own implementation of <code>Lazy&lt;T&gt;</code> for .NET 3.5 (with a simpler multi-thread policy), and I bumped into the following problem:</p>
  
  <p>Lazy has basically two types of constructors:</p>
  
  <pre><code>class Lazy&lt;T&gt; {
  
      public Lazy(){...} // ctor #1
  </code></pre>
  
  <p>which uses T's default constructor for creating an instance of T, and</p>
  
  <pre><code>    public Lazy(Func&lt;T&gt; func){...} // ctor #2
  </code></pre>
  
  <p>which lets the caller decide how the instance of T is created.</p>
  
  <p>Now here's the problem: </p>
  
  <p>If I want compile-time checking for the 1st ctor I will add a restriction</p>
  
  <pre><code>class Lazy&lt;T&gt; where T: new() {...}
  </code></pre>
  
  <p>at the class level. This will allow me to use <code>new T()</code> to create an instance; but this restriction is not necessary for the 2nd ctor, and worse, it also restricts the types I can use (to those with a default ctor)</p>
  
  <p>If I want to be able to use any type with the 2nd ctor, I will not set any restriction, and in the 1st ctor will use reflection to make sure <code>T</code> does have a default ctor. This approach, however, will lack the compile-time check, and will only throw a runtime  exception if the 1st ctor is used with the wrong type.</p>
  
  <p>My question is: Can I get the best of both worlds?  </p>
  
  <p>Ideally, I would like to get the compile-time check for every use of ctor #1, but at the same time be able to use ctor #2 for types that don't have a default ctor.</p>
  
  <p>How does the Microsoft implementation do this? (I don't readily have access to the .NET 4 sources or dlls).</p>
  
  <p>EDIT: (After "Reflector-ing" the MS assembly)  </p>
  
  <p>I checked the reference implementation and it doesn't do compile-time checks.<br>
  It uses reflection for the 'default ctor' case, of course accompanied by the runtime exception if things go bad.</p>