Search code examples
c#genericsbackwards-compatibilitymethod-resolution-order

Removing generic parameter from method signiture


I have a method like this in my library

public void Foo<T>(IQueryable<T> input)
{
    //T is never used and the code compiles when I remove T
} 

I want to refactor it and remove the generic parameter.

public void Foo(IQueryable input) { ... }

How does it affect the code dependent on my library? Do they need to do a rebuild?
Do they encounter compile error?
What if they have used reflection to call this method?

If I create both of them then the method resolution will always pick the generic one. How can I make the generic one deprecate and obsolete in later versions?


Solution

  • Foo<T>() is called Foo`1 in the compiled code. So it is not the same as Foo() that is just called Foo in the compiled code.

    Based on your question, you have this on a public API and you need backward compatibility. If it was me, I would change it to the following:

    [Obsolete("Call Foo2() instead of the deprecated Foo()", true)]
    public void Foo<T>(IQueryable<T> input)
    {
        Foo2(input);
    }
    
    public void Foo2(IQueryable input)
    {
    ...
    }
    

    Anything that is compiled against this new version will complain if it uses the old method. This is true both for inhouse and 3rd party code, that is why I would include the explanation in the error message what to do next.