问题
The following code sample prints:
T
T[]
T[]
While first two lines are as expected, why compiler selected param array for a regular array?
public class A
{
public void Print<T>(T t)
{
Console.WriteLine("T");
}
public void Print<T>(params T[] t)
{
Console.WriteLine("T[]");
}
}
class Program
{
static void Main(string[] args)
{
A a = new A();
a.Print("string");
a.Print("string","string");
a.Print(new string[] {"a","b"});
}
}
回答1:
Under the hood
a.Print("string","string");
is just syntactic sugar for
a.Print(new string[]{"string","string"});
EDIT: Like I said, the params
keyword only automagically creates the array for you, you tell the compiler: either accept an array of T
directly or use the X input params to construct that array.
回答2:
It addition to what others have said, the params keyword also causes a ParamArrayAttribute to the generated for array parameter. So, this...
public void Print<T>(params T[] t) { }
Is generated by the compiler as...
public void Print<T>([ParamArray] T[] t); { }
It is that attribute which indicates to the compiler and the IDE that the method can be called using simpler syntax...
a.Print("string", "string");
rather than...
a.Print(new string[] { "string", "string" });
回答3:
I think this actually has more to do with type inference than with the params keyword. The inference engine assumes on the third line that the type of T is string[] and therefore passes it to the first method.
try Console.WriteLine(typeof(T)) if you don't believe me
回答4:
when having the params keyword, the compiler will do a little bit of translation for the formal function declaration, as well as the actual function call.
Formal function declaration:
Under the hood, the IL will be translated to essentially the same as
public void Print<T>(T[] array);
Except, when compiling, the actual function call will be checked for syntax translation. Meaning,
a.Print("string1", "string2");
Becomes the same IL code as
a.Print(new string[]{"string1", "string2"});
That is why line 2 and 3 are the same output, because under the hood, they got translated to the exact same IL.
Question about why line 3 is not print "T" is because, .NET compiler will always try to find the best overloaded match, and so both line 2 and 3 called to the T[] version instead of the plain T.
回答5:
Exactly as arul said. If you open up the project in reflector, you'll see the following:
a.Print<string>(new string[] { "string", "string" });
回答6:
Params allows you to pass multiple objects of the same type. it is a shortcut way of passing array
来源:https://stackoverflow.com/questions/711828/how-exactly-keyword-params-work