以下代码示例打印:
T
T[]
T[]
虽然前两行是预期的,但为什么编译器为常规数组选择了param数组?
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"});
}
}
答案 0 :(得分:10)
引擎盖下
a.Print("string","string");
只是
的语法糖a.Print(new string[]{"string","string"});
编辑:就像我说的那样,params
关键字只为你自动创建数组,你告诉编译器:直接接受T
数组或使用X输入参数构造该数组
答案 1 :(得分:5)
除了其他人所说的, params 关键字还会导致ParamArrayAttribute生成为数组参数。所以,这......
public void Print<T>(params T[] t) { }
由编译器生成为......
public void Print<T>([ParamArray] T[] t); { }
该属性向编译器和IDE指示可以使用更简单的语法调用该方法...
a.Print("string", "string");
而不是......
a.Print(new string[] { "string", "string" });
答案 2 :(得分:0)
Params允许您传递多个相同类型的对象。它是传递数组的快捷方式
答案 3 :(得分:0)
我认为这实际上与类型推断有关,而不是与params关键字有关。推理引擎在第三行假设T的类型是string [],因此将它传递给第一个方法。
如果你不相信我,试试Console.WriteLine(typeof(T))
答案 4 :(得分:0)
当使用params关键字时,编译器将对正式函数声明以及实际函数调用进行一些翻译。
正式的职能声明:
在幕后,IL将被翻译为与
基本相同public void Print<T>(T[] array);
除了编译时,将检查实际函数调用的语法翻译。意思,
a.Print("string1", "string2");
与
成为相同的IL代码a.Print(new string[]{"string1", "string2"});
这就是为什么第2行和第3行是相同的输出,因为在引擎盖下,它们被转换为完全相同的IL。
关于为什么第3行不打印“T”的问题是因为,.NET编译器总是试图找到最佳的重载匹配,因此第2行和第3行都调用T []版本而不是普通T.
答案 5 :(得分:0)
正如阿鲁所说。如果您在反射器中打开项目,您将看到以下内容:
a.Print<string>(new string[] { "string", "string" });