title: .NET equivalent for Java wildcard generics <?> with co- and contra- variance?
body: <p>I'm stuck trying to translate some Java code that uses (bounded) wildcard generics to C#. 
  My  problem is, Java seems to allow a generic type to be both covariant and contravariant when used with a wildcard. For instance: </p>
  
  <p><strong>Java:</strong></p>
  
  <pre><code>interface IInterf { }
  
  class Impl implements IInterf { }
  
  interface IGeneric1&lt;T extends Impl&gt; {
      void method1(IGeneric2&lt;?&gt; val);
      void method1WithParam(T val);
  }
  
  interface IGeneric2&lt;T extends Impl&gt; {
      void method2(IGeneric1&lt;?&gt; val);
  }
  
  abstract class Generic&lt;T extends Impl&gt; implements IGeneric1&lt;T&gt;, IGeneric2&lt;T&gt; {
      public void method1(IGeneric2&lt;?&gt; val2) {
          val2.method2(this);
      }
  }
  </code></pre>
  
  <p>...works.</p>
  
  <p><em>C# equivalent (?)</em></p>
  
  <pre><code>interface IInterf { }
  
  class Impl : IInterf { }
  
  interface IGeneric1&lt;T&gt; where T:Impl {
    //Java was: 
    //void method1(IGeneric2&lt;?&gt; val2);
      void method1(IGeneric2&lt;Impl&gt; val);
      void method1WithParam(T to);
  }
  
  interface IGeneric2&lt;T&gt;where T:Impl {
      void method2(IGeneric1&lt;Impl&gt; val);
  }
  
  abstract class Generic&lt;T&gt; : IGeneric1&lt;T&gt;, IGeneric2&lt;T&gt; where T : Impl
  {
    //Java was: 
    //public void method1(IGeneric2&lt;?&gt; val2) {
      public void method1(IGeneric2&lt;Impl&gt; val2)
      {
           val2.method2(this); //'this': Argument type 'Generic&lt;T&gt;' is not 
                               //assignable to parameter type 'IGeneric1&lt;Impl&gt;'
      }
  
      public abstract void method1WithParam(T to);
      public abstract void method2(IGeneric1&lt;Impl&gt; val);
  }
  </code></pre>
  
  <p>...fails to compile - see the error in the comment. Which is to be expected, since IGeneric's generic parameter is not marked 'out' for covariance. </p>
  
  <p>If I change this:</p>
  
  <pre><code>interface IGeneric1&lt;T&gt; where T:Impl {
  </code></pre>
  
  <p>to this </p>
  
  <pre><code>interface IGeneric1&lt;out T&gt; where T:Impl 
  </code></pre>
  
  <p>the error goes away, but another one appears, for the declaration of the method that takes a generic parameter inside the same interface:</p>
  
  <pre><code>interface IGeneric1&lt;T&gt; where T:Impl {
      void method1WithParam(T val);  //Parameter must be input-safe. 
                        //Invalid variance: The type parameter 'T' must be
                        //contravariantly valid on 'IGeneric1&lt;out T&gt;'.
  </code></pre>
  
  <p>Suggestions?</p>
  
  <p>[Also see the <a href="https://stackoverflow.com/q/14289518/11545">follow-up question</a> for a somewhat harder scenario]</p>