Overloading, generic type inference and the 'params' keyword

假装没事ソ 提交于 2019-12-07 06:20:18

问题


I just noticed a strange behavior with overload resolution.

Assume that I have the following method :

public static void DoSomething<T>(IEnumerable<T> items)
{
    // Whatever

    // For debugging
    Console.WriteLine("DoSomething<T>(IEnumerable<T> items)");
}

Now, I know that this method will often be called with a small number of explicit arguments, so for convenience I add this overload :

public static void DoSomething<T>(params T[] items)
{
    // Whatever

    // For debugging
    Console.WriteLine("DoSomething<T>(params T[] items)");
}

Now I try to call these methods :

var items = new List<string> { "foo", "bar" };
DoSomething(items);
DoSomething("foo", "bar");

But in both cases, the overload with params is called. I would have expected the IEnumerable<T> overload to be called in the case of a List<T>, because it seems a better match (at least to me).

Is this behavior normal ? Could anyone explain it ? I couldn't find any clear information about that in MSDN docs... What are the overload resolution rules involved here ?


回答1:


Section 7.4.3 of the C# 3.0 specification is the relevant bit here. Basically the parameter array is expanded, so you're comparing:

public static void DoSomething<T>(T item)

and

public static void DoSomething<T>(IEnumerable<T> item)

The T for the first match is inferred to be List<string> and the T for the second match is inferred to be string.

Now consider the conversions involved for argument to parameter type - in the first one it's List<string> to List<string>; in the second it's List<string> to IEnumerable<string>. The first conversion is a better than the second by the rules in 7.4.3.4.

The counterintuitive bit is the type inference. If you take that out of the equation, it will work as you expect it to:

var items = new List<string> { "foo", "bar" };
DoSomething<string>(items);
DoSomething<string>("foo", "bar");

At that point, there's only one applicable function member in each call.



来源:https://stackoverflow.com/questions/1820551/overloading-generic-type-inference-and-the-params-keyword

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