Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
301 views
in Technique[技术] by (71.8m points)

c# - Generic Method Resolution

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...