title: Generic type inference with multiply-implemented covariant interfaces, how to work around it?
body: <p>Consider this silly program that does nothing:</p>
  
  <pre><code>interface I&lt;out T&gt; { }
  class A1 : I&lt;A1&gt; { }
  class A2 : A1, I&lt;A2&gt; { }
  class B1 { }
  class B2 : B1, I&lt;B2&gt; { }
  class C1 : I&lt;A1&gt; { }
  class C2 : C1, I&lt;A2&gt; { }
  
  static class Program
  {
      static void f&lt;T&gt;(I&lt;T&gt; obj)
      {
      }
  
      static void Main()
      {
          f&lt;A1&gt;(new A2());
          f&lt;A2&gt;(new A2());
          f&lt;B1&gt;(new B2());
          f&lt;B2&gt;(new B2());
          f&lt;A1&gt;(new C2());
          f&lt;A2&gt;(new C2());
      }
  }
  </code></pre>
  
  <p>This shows that <code>A2</code> and <code>C2</code> implement both <code>I&lt;A1&gt;</code> and <code>I&lt;A2&gt;</code>, and that <code>B2</code> implements both <code>I&lt;B1&gt;</code> and <code>I&lt;B2&gt;</code>.</p>
  
  <p>However, modifying this to</p>
  
  <pre><code>static void Main()
  {
      f(new A2());
      f(new B2());
      f(new C2());
  }
  </code></pre>
  
  <p>shows that on the first and third lines, <code>f</code>'s generic type argument cannot be inferred from the passed argument, yet on the second line, it can be.</p>
  
  <p>I understand what it is that the compiler is doing here, so that doesn't need explaining. But how can I work around this? Is there some way to modify this so that I <em>can</em> define the interface on both the base and the derived class, yet have type inference work when passing the derived class?</p>
  
  <p>What I had in mind was to look for a way to "hide" a base class's implemented interfaces, so that the compiler doesn't see them and use them, even though they do exist. However, C# doesn't seem to provide an option to do so.</p>
  
  <p><em>Clarification</em>: in my silly example program, <code>A1</code> implements <code>I</code> with itself as the generic type argument. I do have that in my real code, but I also have classes that implement <code>I</code> with a different generic type argument, and have added <code>C1</code> and <code>C2</code> to my example code for that reason.</p>