打印以下代码示例:
T
T[]
T[]
虽然前两行符合预期,但为什么编译器选择 param 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"});
}
}
在引擎盖下
a.Print("string","string");
只是
的语法糖a.Print(new string[]{"string","string"});
编辑:就像我说的,
params
关键字只会自动为您创建数组,您告诉编译器:要么直接接受T
数组,要么使用X输入参数来构造该数组。
除了其他人所说的之外,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" });
我认为这实际上与类型推断有关,而不是与 params 关键字有关。 推理引擎在第三行假设 T 的类型是 string[],因此将其传递给第一个方法。
如果你不相信我,请尝试 Console.WriteLine(typeof(T))
当有 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。
正如阿鲁尔所说。如果您在 Reflector 中打开该项目,您将看到以下内容:
a.Print<string>(new string[] { "string", "string" });
Params 允许您传递相同类型的多个对象。 这是传递数组的快捷方式