English 中文(简体)
Overloading, generic type inference and the params keyword
原标题:

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 ?

最佳回答

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.

问题回答

暂无回答




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签