2

I was surprised to find out that the return type on a method can create an overload ambiguity when passing the method in to another method. Since the return type is not part of the signature, it's hard to see how changing the return value could create ambiguity where it had not previously existed. Yet this seems to be the case for void and Task. Consider the following:

    class Signature
    {
        static public void Overload(Func<Task> countasync)
        {
        }
        static public void Overload(Action count)
        {
        }
    }

    void Decrement() { }
    Task IncrementAsync() { return Task.CompletedTask; }

    void TestSig()
    {
        Signature.Overload(this.IncrementAsync); // no compile time error
        Signature.Overload(this.Decrement); // compile time error: this call is ambiguous 
    }

Is there a way to define the Overload argument types so that the second call is not ambiguous, while still allowing the first call?

sjb-sjb
  • 1,112
  • 6
  • 14

1 Answers1

1

No, there's no way to fix the overload resolution.

But, you can remove the ambiguity at the cost of slightly uglier call site code:

Signature.Overload( () => this.Decrement() );

The compiler will correctly deduce the overload in that case.

Kyle
  • 6,500
  • 2
  • 31
  • 41
  • It seems that the cause of the ambiguity is the fact that delegate types (unlike method signatures) are differentiated by return type as well as by parameter type. An upside to this is that you can, for example, have different event types based on the return type of the event handler. – sjb-sjb Oct 07 '17 at 11:58