Search code examples
c#reflectionambiguous-call

How come this does not throw some kind of error regarding ambiguous methods?


I was messing around to see what I could and could not do with regards to generics. I have this situation and as far as I'm concerned the compiler should throw an error with regards to ambiguous method calls but it compiles perfectly fine. Why is that?

public interface IFunctionStrategy<T>
{
    T Strategy(params object[] parameters);
}

public class FunctionStrategyBase<T> : IFunctionStrategy<T>
{
    public virtual T Strategy(params object[] parameters)
    {
        MethodBase current = MethodBase.GetCurrentMethod();
        return (T)GetType().InvokeMember(current.Name, BindingFlags.InvokeMethod | BindingFlags.Public, Type.DefaultBinder, this, parameters);
    }

}

public class ConnectionConnect : FunctionStrategyBase<int>
{
    public int Strategy(int i)
    {
        return i;
    }
}

Solution

  • There is no ambiguity. As you said in the comments yourself, the signature is different. Inside of the context of ConnectionConnect, there is now a

    Strategy(int i)

    and a

    Strategy(params object[] parameters) which is inherited from the FunctionStrategyBase

    which is perfectly acceptable overloading. Regardless of what happens at runtime and the odd behaviour that could occur if you were unaware of the mechanics of these functions, the compiler sees no strict problems with this.

    When calling at runtime, the program will use the closest matching signature, before checking for signatures that it can make valid implicit casts to. If you pass a single int to Strategy, the Strategy(int i) method will be used. If you did not have this, it would then implicitly box your int and pass it to Strategy(params object[] parameters) as a feature of the language.