开发者

Ambiguous call error with overloaded method that takes 2 delegates with different return types

class Program
{
    public delegate void VoidMethodDelegate();
    public delegate int IntMethodDelegate();

    static void Main(string[] args)
    {
        Test(IntMethod);
        Test(VoidMethod);
    }

    static int IntMethod()
    {
        return 1;
    }

    static void VoidMethod()
    {
    }

    static void Test(VoidMethodDelegate method)
    {
    }

    static void Test(IntMethodDelegate method)
    {
    }
}

I am trying to set up an overloaded method that will take two different types of delegates. The de开发者_如何学Golegates differ only by return type -- in both cases they take no input parameters. So in the example above, I would like to be able to call Test() and pass it either a method that returns void, or a method that returns int. When I compile the code above, I get these errors:

error CS0121: The call is ambiguous between the following methods or properties: 'ConsoleApplication1.Program.Test(ConsoleApplication1.Program.VoidMethodDelegate)' and 'ConsoleApplication1.Program.Test(ConsoleApplication1.Program.IntMethodDelegate)'

error CS0407: 'int ConsoleApplication1.Program.IntMethod()' has the wrong return type

error CS0121: The call is ambiguous between the following methods or properties: 'ConsoleApplication1.Program.Test(ConsoleApplication1.Program.VoidMethodDelegate)' and 'ConsoleApplication1.Program.Test(ConsoleApplication1.Program.IntMethodDelegate)'

I know I can work around the errors if I create the delegates with new instead of just passing the method directly, like this:

    static void Main(string[] args)
    {
        Test(new IntMethodDelegate(IntMethod));
        Test(new VoidMethodDelegate(VoidMethod));
    }

But that syntax is messy, and I'd prefer to be able to pass the method directly, instead of having to wrap it in a call to new. The only solution I've seen is to get rid of the overloaded version of Test() and instead use two different methods, each with a different name.

Can anyone tell me why the compiler is complaining that this is ambiguous? I don't understand whhy the compiler can't decide which of the two overloads to use.


Basically this is a corollary of how overloading is performed, and how method group conversions are resolved. I can try to wade through the spec to find the exact reasons if you like, but the bad news is that's just the way it is. It's possible there's a compiler bug in this case, but it's more likely that it's just a tricky bit of the spec.

I think that this SO question may be relevant, but I haven't checked yet.

Rather than resolve it using new, I would suggest take the option of using different method names. Overloading has all kinds of sneaky corner cases - this one is at least relatively harmless in that it's causing a compile-time error rather than picking the overload you don't want at execution time. Removing overloading is often a good thing :)

EDIT: I'm pretty sure that other SO question is relevant, actually. I suggest you get yourself a cup of coffee, the C# 4 spec, and then read Eric's answer very carefully. Then change the method names so you don't have to think about it any more.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜