title: Partial generic type inference possible in C#?
body: <p>I am working on rewriting my fluent interface for my IoC class library, and when I refactored some code in order to share some common functionality through a base class, I hit upon a snag.</p>
  
  <p><strong>Note</strong>: This is something I <em>want</em> to do, not something I <em>have</em> to do. If I have to make do with a different syntax, I will, but if anyone has an idea on how to make my code compile the way I want it, it would be most welcome.</p>
  
  <p>I want some extension methods to be available for a specific base-class, and these methods should be generic, with one generic type, related to an argument to the method, but the methods should also return a specific type related to the particular descendant they're invoked upon.</p>
  
  <p>Better with a code example than the above description methinks.</p>
  
  <p>Here's a simple and complete example of what <em>doesn't</em> work:</p>
  
  <pre><code>using System;
  
  namespace ConsoleApplication16
  {
      public class ParameterizedRegistrationBase { }
      public class ConcreteTypeRegistration : ParameterizedRegistrationBase
      {
          public void SomethingConcrete() { }
      }
      public class DelegateRegistration : ParameterizedRegistrationBase
      {
          public void SomethingDelegated() { }
      }
  
      public static class Extensions
      {
          public static ParameterizedRegistrationBase Parameter&lt;T&gt;(
              this ParameterizedRegistrationBase p, string name, T value)
          {
              return p;
          }
      }
  
      class Program
      {
          static void Main(string[] args)
          {
              ConcreteTypeRegistration ct = new ConcreteTypeRegistration();
              ct
                  .Parameter&lt;int&gt;("age", 20)
                  .SomethingConcrete(); // &lt;-- this is not available
  
              DelegateRegistration del = new DelegateRegistration();
              del
                  .Parameter&lt;int&gt;("age", 20)
                  .SomethingDelegated(); // &lt;-- neither is this
          }
      }
  }
  </code></pre>
  
  <p>If you compile this, you'll get:</p>
  
  <pre><code>'ConsoleApplication16.ParameterizedRegistrationBase' does not contain a definition for 'SomethingConcrete' and no extension method 'SomethingConcrete'...
  'ConsoleApplication16.ParameterizedRegistrationBase' does not contain a definition for 'SomethingDelegated' and no extension method 'SomethingDelegated'...
  </code></pre>
  
  <p>What I want is for the extension method (<code>Parameter&lt;T&gt;</code>) to be able to be invoked on both <code>ConcreteTypeRegistration</code> and <code>DelegateRegistration</code>, and in both cases the return type should match the type the extension was invoked on.</p>
  
  <p>The problem is as follows:</p>
  
  <p>I would like to write:</p>
  
  <pre><code>ct.Parameter&lt;string&gt;("name", "Lasse")
              ^------^
              notice only one generic argument
  </code></pre>
  
  <p>but also that <code>Parameter&lt;T&gt;</code> returns an object of the same type it was invoked on, which means:</p>
  
  <pre><code>ct.Parameter&lt;string&gt;("name", "Lasse").SomethingConcrete();
  ^                                     ^-------+-------^
  |                                             |
  +---------------------------------------------+
     .SomethingConcrete comes from the object in "ct"
     which in this case is of type ConcreteTypeRegistration
  </code></pre>
  
  <p>Is there any way I can trick the compiler into making this leap for me?</p>
  
  <p>If I add two generic type arguments to the <code>Parameter</code> method, type inference forces me to either provide both, or none, which means this:</p>
  
  <pre><code>public static TReg Parameter&lt;TReg, T&gt;(
      this TReg p, string name, T value)
      where TReg : ParameterizedRegistrationBase
  </code></pre>
  
  <p>gives me this:</p>
  
  <pre><code>Using the generic method 'ConsoleApplication16.Extensions.Parameter&lt;TReg,T&gt;(TReg, string, T)' requires 2 type arguments
  Using the generic method 'ConsoleApplication16.Extensions.Parameter&lt;TReg,T&gt;(TReg, string, T)' requires 2 type arguments
  </code></pre>
  
  <p>Which is just as bad.</p>
  
  <p>I can easily restructure the classes, or even make the methods non-extension-methods by introducing them into the hierarchy, but my question is if I can avoid having to duplicate the methods for the two descendants, and in some way declare them only once, for the base class.</p>
  
  <p>Let me rephrase that. Is there a way to change the classes in the first code example above, so that the syntax in the Main-method can be kept, without duplicating the methods in question?</p>
  
  <p>The code will have to be compatible with both C# 3.0 and 4.0.</p>
  
  <hr>
  
  <p><strong>Edit</strong>: The reason I'd rather not leave both generic type arguments to inference is that for some services, I want to specify a parameter value for a constructor parameter that is of one type, but pass in a value that is a descendant. For the moment, matching of specified argument values and the correct constructor to call is done using both the name and the type of the argument.</p>
  
  <p>Let me give an example:</p>
  
  <pre><code>ServiceContainerBuilder.Register&lt;ISomeService&gt;(r =&gt; r
      .From(f =&gt; f.ConcreteType&lt;FileService&gt;(ct =&gt; ct
          .Parameter&lt;Stream&gt;("source", new FileStream(...)))));
                    ^--+---^               ^---+----^
                       |                       |
                       |                       +- has to be a descendant of Stream
                       |
                       +- has to match constructor of FileService
  </code></pre>
  
  <p>If I leave both to type inference, the parameter type will be <code>FileStream</code>, not <code>Stream</code>.</p>