关键字“params”到底如何工作?

问题描述 投票:0回答:6

打印以下代码示例:

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"});
    }
}
c# generics parameters
6个回答
10
投票

在引擎盖下

a.Print("string","string");

只是

的语法糖
a.Print(new string[]{"string","string"});

编辑:就像我说的,

params
关键字只会自动为您创建数组,您告诉编译器:要么直接接受
T
数组,要么使用X输入参数来构造该数组。


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

0
投票

我认为这实际上与类型推断有关,而不是与 params 关键字有关。 推理引擎在第三行假设 T 的类型是 string[],因此将其传递给第一个方法。

如果你不相信我,请尝试 Console.WriteLine(typeof(T))


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。


0
投票

正如阿鲁尔所说。如果您在 Reflector 中打开该项目,您将看到以下内容:

a.Print<string>(new string[] { "string", "string" });

0
投票

Params 允许您传递相同类型的多个对象。 这是传递数组的快捷方式

© www.soinside.com 2019 - 2024. All rights reserved.