开发者

Why generic overload results ambiguous?

开发者 https://www.devze.com 2023-04-06 13:31 出处:网络
I wondering why the generic overloading is not allowed, and it results in a compiler error of \"ambiguous\" resolution.

I wondering why the generic overloading is not allowed, and it results in a compiler error of "ambiguous" resolution.

Here is the sample code:

class Program
{
    static void Main(string[] args)
    {
        var p = new Program();

        p.DoWork(new First());
        p.DoWork(new Second());
        p.DoWork(new Multi());    //ambiguous: that's right!

        p.Test<IFirst>(new First());  //ambiguous???
    }


    private void DoWork(IFirst arg) { }

    private void DoWork(ISecond arg) { }

    private void Test<T>(T arg) where T : IFirst { }

    private void Test<T>(T arg) where T : ISecond { }
}


interface IFirst { }

interface ISecond { }

class First : IFirst { }

class Second : ISecond { }

class Multi : IFirst, ISecond { }

I am not able to feel the difference between the explicit form (DoWork) and the generic one, having explicitly declared the interface to consider. Why the first one is allowed and the second does not?

My goal is having two "Test" methods behaving similarly, but not exactly.

Any workaround (other than naming the methods differently)?

Thank 开发者_Go百科you everybody in advance.


Constraints are not part of the signature.


This code will not compile even without making any calls to the methods at all. The problem here is that since generic type constraints are not part of the methods' signatures, the two Test<T> declarations have the same signature:

private void Test<T>(T arg) where T : IFirst { }

private void Test<T>(T arg) where T : ISecond { }

This will not compile for the same reason that the following would also not compile:

private void Foo() { }

private void Foo() { }

The compiler will complain that a method with the same signature has already been declared.

Notice that the DoWork methods do not have this problem:

private void DoWork(IFirst arg) { }

private void DoWork(ISecond arg) { }

Since parameter types are part of the method signature, here we are talking about two standard overloads of one method, which is perfectly OK.

0

精彩评论

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

关注公众号