There are several ways to resolve errors when overloading method groups.
Method 1: enter a group of methods
CallWithDelegate((SomeDelegateWithoutParameters)SomeOverloadedMethod); CallWithDelegate((SomeDelegateWithParameter)SomeOverloadedMethod);
This eliminates overload. This is a rather unusual syntax in the wild, but it works (C # 5 spec ยง6.6 Converting method groups):
As with all other implicit and explicit conversions, the casting operator can be used to explicitly perform a transformation of a group of methods.
<sub> [...] sub>
Method groups can influence overload resolution and participate in type inference.
Method 2: explicitly specify the delegate
CallWithDelegate(new SomeDelegateWithoutParameters(SomeOverloadedMethod)); CallWithDelegate(new SomeDelegateWithParameter(SomeOverloadedMethod));
This is the same as the previous method without syntactic sugar. See the specification in ยง7.6.10.5. Delegate expression formats for more details.
Processing time binding of an expression-create-expression of the form new D(E) , where D is the delegate type and E is the expression, consists of the following steps:
- If
E is a group of methods, the delegate creation expression is treated in the same way as the conversion of a group of methods (ยง6.6) from E to D
<sub> [...] sub>
Even an example close to your question:
As described above, when a delegate is created from a group of methods, the formal list of parameters and the type of delegate return determine which of the overloaded methods to choose. In the example
delegate double DoubleFunc(double x); class A { DoubleFunc f = new DoubleFunc(Square); static float Square(float x) { return x * x; } static double Square(double x) { return x * x; } }
the Af field is initialized by a delegate who refers to the second Square method, because this method exactly matches the formal parameter list and the DoubleFunc return DoubleFunc . If the second Square method were not present, a compile-time error occurred.
Method 3: use lambda
CallWithDelegate(() => SomeOverloadedMethod()); CallWithDelegate(i => SomeOverloadedMethod(i)); CallWithDelegate((int i) => SomeOverloadedMethod(i)); // Explicit types, if needed
This form is not ambiguous, but has indirectness (lambda is called, and then the target method is called). It can be optimized by JIT, though, and it most likely will not have a visible impact on performance in any way.
Method 4: use anonymous delegates
CallWithDelegate(delegate() { SomeOverloadedMethod(); }); CallWithDelegate(delegate(int i) { SomeOverloadedMethod(i); });
This is equivalent to lambda calls, but it uses the more massive (and older) delegate syntax.
If you want to know the exact rules for resolving overloads, they are described in the specification in ยง7.5.3. Overload Resolution.