关键字'params'究竟是如何工作的?

时间:2009-04-02 22:12:34

标签: c# generics compiler-construction parameters

以下代码示例打印:

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"});
    }
}

6 个答案:

答案 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" });