Как именно работает ключевое слово «params»? - PullRequest
6 голосов
/ 03 апреля 2009

Печатается следующий образец кода:

T
T[]
T[]

Хотя первые две строки соответствуют ожидаемым, почему компилятор выбрал массив параметров для обычного массива?

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 ]

10 голосов
/ 03 апреля 2009

под капотом

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

- это просто синтаксический сахар для

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

РЕДАКТИРОВАТЬ: Как я уже сказал, ключевое слово params только автоматически создает массив для вас, вы говорите компилятору: либо принимайте массив T напрямую, либо используйте входные параметры X для создания этого массива.

5 голосов
/ 03 апреля 2009

Кроме того, что говорят другие, ключевое слово 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 голосов
/ 03 апреля 2009

Точно так, как сказал Арул. Если вы откроете проект в отражателе, вы увидите следующее:

a.Print<string>(new string[] { "string", "string" });
0 голосов
/ 03 апреля 2009

при наличии ключевого слова 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 голосов
/ 03 апреля 2009

Я думаю, что это на самом деле больше связано с выводом типа, чем с ключевым словом params. Механизм вывода предполагает в третьей строке, что тип T - это строка [], и поэтому передает его первому методу.

попробуйте Console.WriteLine (typeof (T)), если вы мне не верите

0 голосов
/ 03 апреля 2009

Params позволяет передавать несколько объектов одного типа. это быстрый способ передачи массива

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...