Generic Method Resolution

ε祈祈猫儿з 提交于 2019-12-07 06:10:47

问题


Consider the following code:

public class Tests
{
    public void Test()
    {
        Assert.AreEqual("Int", DoSomething(1));
    }

    public static string DoSomething<T>(T value)
    {
        return "Generic";
    }

    public static string DoSomething(int value)
    {
        return "Int";
    }
}

As expected, the non-generic DoSomething method will be invoked. Now consider the following modification:

public class Tests
{
    public void Test()
    {
        Assert.AreEqual("Int", DoSomething(1));
    }

    public static string DoSomething<T>(T value)
    {
        return "Generic";
    }

    public static string DoSomething<T>(int value)
    {
        return "Int";
    }
}

The only thing I've changed is adding the T type parameter to the second overload, thus making it generic. Note that the type parameter is not used.

That modification causes the first DoSomething method to be called. Why? The compiler has all the information it needs in order to choose the second method.

Can you please explain why, or even better, point me to the section of the C# specification that explains this behavior?


回答1:


In your call, you're not specifying a type argument - so the compiler would have to infer the type of T. It can't do that for your second method, because the type parameter is never mentioned in the declared parameters. Therefore, that overload is not applicable, and is ignored.

If you specify a type argument to the call, e.g. any of

DoSomething<int>(1)
DoSomething<object>(1)
DoSomething<string>(1)

... then in all cases the second overload will be called.

From section 7.6.5.1 of the C# 5 spec, (method invocations) when constructing the set of candidate methods:

  • If F is generic and M has no type argument list, F is a candidate when:
    • Type inference (§7.5.2) succeeds, inferring a list of type arguments for the call, and
    • Once the inferred type arguments are substituted for the corresponding method type parameters, all constructed types in the parameter list of F satisfy their constraints (§4.4.4), and the parameter list of F is applicable with respect to A (§7.5.3.1).

As type inference doesn't succeed, the second method isn't in the candidate set, so by the time we get to real overload resolution, the set just has a single method in (the first one).




回答2:


the compiler can not determine the type of pattern in the call DoSomething(1), but if you specify [int] it will be selected another method.



来源:https://stackoverflow.com/questions/25368252/generic-method-resolution

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!