2016-09-30 5 views
2

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

Когда это становится обязательным для указания типа?

Write(1); 
Write<int>(1); 
Write<string>("test"); 
Write("test"); 

private static void Write<T>(T param) 
{ 
    Console.WriteLine(param); 
} 

ответ

5

Компилятор попытается разрешить аргумент типа во время компиляции. В тех случаях, когда это возможно, это делается автоматически, без необходимости указывать явный тип. Во всех остальных случаях, когда компилятор не может определить аргумент типа, компилятор выдает ошибку, и вы не можете скомпилировать свое приложение.

В вашем примере Write(1) аргумент 1 имеет тип int. Поэтому компилятор сообщает, что T должен быть int, поэтому звонок эквивалентен Write<int>(1). Аналогично Write("test"), "test" имеет тип string, поэтому компилятор заключит, что T - string.

Как правило, это относится к времени компиляции типа аргумента, который вы передаете функции. Так что если у вас есть строка с типом времени компиляции из object, T будет object:

object arg = "foo"; 

Write(arg); // arg is object 

// this is equivalent to this: 
Write<object>(arg); 

Таким образом, хотя вы передаете строку, его компиляция типа времени object так, что единственная информация, компилятор может использовать здесь.

Кроме того, вы можете явно указать аргумент типа, когда хотите, чтобы компилятор использовал другой тип, чем аргумент времени компиляции того, что вы ему передаете. В приведенном выше примере вы можете использовать Write<object>(1), что приведет к тому, что целое число 1 будет отлито в object. Однако на практике это обычно разрушает цель общих методов и может иметь фактические последствия, даже если вам не нужен доступ к типу времени компиляции фактического параметра. Например, типы значений будут вставляться в коробку при передаче как object, но общие методы позволяют сохранить их как типы значений - помните, что определение общего метода (то же самое относится к типам) является эквивалентным заданию перегрузки с , каждый другой действительный Значение аргумента generic type (так что вы обычно имеете бесконечную копию методов).

Конечно, определение типа компилятора также работает с несколькими аргументами:

void Write<T1, T2>(T1 arg1, T2 arg2) 
{ … } 

Write(1, "foo"); 
// is equivalent to 
Write<int, string>(1, "foo"); 

Однако, когда компилятор не в состоянии вывести хотя бы один аргумент типа, вы должны указать все из них вызов.

+0

Благодарим за подробное объяснение. – DotNetLearner

2

Обязательно указывать тип, когда компилятор не может его вывести, или когда вас не устраивает то, что компилятор сообщает.

3

Это не является обязательным в этой ситуации, потому что параметр param является общим (компилятор разрешает его так).

Это означает, что это обязательно, если аргумент типа не указан в качестве параметра.

1

Там нет никакой разницы между

Write<string>("test"); 
Write("test"); 

Но есть разницы, когда вы указываете точно не тип параметра, но кабриолет, например

Write<object>("test"); 
Write("test"); 

Просто попробуйте параметр типа печати и будет см. разницу

private static void Write<T>(T param) 
{ 
    Console.WriteLine(typeof(T)); 
    Console.WriteLine(param); 
} 
Смежные вопросы