2009-04-02 3 views
5

В следующем примере кода печатает:Как точно работает ключевое слово «params»?

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

Вы задайте много интересных вопросов. –

ответ

10

Под капотом

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

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

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

EDIT: Как я уже сказал, params ключевого слова только автомагически создает массив для вас, компилятора : либо принять массив из T напрямую, либо использовать входные параметры X для построения этого массива.

+0

Перечитайте вопрос. – strager

+0

@strager: Вы должны прочитать вопрос. Арул прав. – Samuel

+0

Хорошо, может быть, я совершенно ничего не понимаю. Можете ли вы немного объяснить свой ответ? – strager

0

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

+0

Как пишут другие, нет такой вещи, как массив params, и нет никакого «сопоставления массиву params». Это просто ключевое слово array и params позволяет писать более компактный синтаксис. –

+0

Извините за неправильное слово ... –

0

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

попытка Console.WriteLine (TypeOf (T)), если вы не верите мне

+0

Первый метод печатает только «T», поэтому вы ошибаетесь. – Prankster

+0

нет, вы не понимаете, что я говорю. Первый механизм вывода отображает T для ввода строки, а третий - T для ввода строки []. Просто замените выходы консоли консолью.WriteLine (typeof (T)); и вы увидите –

+0

@George. Вы ошибаетесь: T будет строкой во всех трех случаях. – LukeH

0

, когда имеющие ключевое слово Params, компилятор будет сделать немного перевода для официального объявления функции, а также фактический вызов функции.

Формальное объявление функции:

Под капотом, IL будут переведены, по существу, такой же, как

public void Print<T>(T[] array); 

Кроме этого, при компиляции, фактический вызов функция будет проверен на синтаксис перевода , Значение,

a.Print("string1", "string2"); 

становится такой же IL код, как

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

Вот почему линия 2 и 3 имеют тот же результат, потому что под капотом, они получили переведены на точно такой же IL.

Вопрос о том, почему строка 3 не печатается «Т», потому что .NET-компилятор всегда будет пытаться найти наилучшее перегруженное соответствие, поэтому обе строки 2 и 3 вызываются в версию T [] вместо простой T .

0

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

a.Print<string>(new string[] { "string", "string" }); 
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" }); 
Смежные вопросы