title: Creating covariant generic types without violating empty interface rules
body: <p>Background: I wanted to "expand" the .NET <code>Lazy&lt;&gt;</code> type to support implicit cast between <code>Lazy&lt;T&gt;</code> and the underlying <code>T</code> object to be able automatically unwrap the containing value. I was able to do so fairly easily:</p>
  
  <pre><code>public class ExtendedLazy&lt;T&gt; : Lazy&lt;T&gt;
  {
      public ExtendedLazy() : base() {}
      public ExtendedLazy(bool isThreadSafe) : base(isThreadSafe) { }
      public ExtendedLazy(Func&lt;T&gt; valueFactory) : base(valueFactory) { }
      // other constructors
  
      public static implicit operator T(ExtendedLazy&lt;T&gt; obj)
      {
          return obj.Value;
      }
  }
  </code></pre>
  
  <p>I wanted to take it a step further by making <code>T</code> covariant so I  could assign an instance of <code>ExtendedLazy&lt;Derived&gt;</code> to <code>ExtendedLazy&lt;Base&gt;</code>. Since variance modifiers are not allowed in class definitions, I had to resort to an empty interface to achieve this:</p>
  
  <pre><code>public interface IExtendedLazy&lt;out T&gt;
  {
  }
  </code></pre>
  
  <p>And changed my class definition to </p>
  
  <p><code>public class ExtendedLazy&lt;T&gt; : Lazy&lt;T&gt;, IExtendedLazy&lt;T&gt;</code></p>
  
  <p>This works fine and I was able to make use of this covariant type:</p>
  
  <pre><code>ExtendedLazy&lt;DerivedClass&gt; derivedLazy = new ExtendedLazy&lt;DerivedClass&gt;();
  IExtendedLazy&lt;BaseClass&gt; baseLazy = derivedLazy;
  </code></pre>
  
  <p>While this compiles and works fine, it goes against <a href="https://msdn.microsoft.com/en-us/library/ms182128.aspx" rel="nofollow">CA1040: Avoid empty interfaces</a> which says using empty interfaces as contracts is a bad design and a code smell (and I'm sure most people agree). My question is, given the inability of the CLR to recognize variant generic types in class definitions, what other ways are around this to make it more consistent with acceptable OO practices? I'd imagine I'm not the only person facing this issue so am hoping to get some insight on this.</p>