I first saw this on Ayende's blog (in a rather more obscure form, admittedly). Once again, work out what will be printed, and why.
Answer:
Then overloading tries to work out which method is "better". If it's a choice between
using System;
class Test
{
static void Main()
{
Foo("Hello");
}
static void Foo(object x)
{
Console.WriteLine("object");
}
static void Foo<T>(params T[] x)
{
Console.WriteLine("params T[]");
}
}
class Test
{
static void Main()
{
Foo("Hello");
}
static void Foo(object x)
{
Console.WriteLine("object");
}
static void Foo<T>(params T[] x)
{
Console.WriteLine("params T[]");
}
}
Answer:
params T[]
is printed. Now why would the compiler choose to create an array when it doesn't have to? Well... there are two stages to this. Firstly, when trying to find overloads which are legitimate candidates to be called, type inference works out that T
should be System.String
. Nothing scary so far.Then overloading tries to work out which method is "better". If it's a choice between
string x
and params string[] x
the former will always win - but at this point it's effectively a choice between object x
andparams string[] x
. (The fact that one is actually a generic method is only relevant in a tie-break situation.) For the purposes of working out "better conversions" the expanded form of the method with the params
parameter is then used. This means that by the time actual conversions are considered, the choices are object x
or string x
- so clearly the latter wins.
Comments
Post a Comment