Почему это работает?

Почему это работает? Я не жалуюсь, просто хочу знать.

void Test()
{    
    int a = 1;
    int b = 2;

    What<int>(a, b);
    // Why does this next line work?
    What(a, b);
}

void What<T>(T a, T b)
{

}
10
задан SLaks 4 May 2010 в 13:42
поделиться

7 ответов

Если вам интересно, как это работает в C # 3.0, вот небольшое видео, в котором я объяснял это еще в 2006 году, когда мы впервые разрабатывали версию этой функции для C # 3.0.

http://blogs.msdn.com/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx

См. Также раздел «Вывод типа» в мой блог:

http://blogs.msdn.com/ericlippert/archive/tags/Type+Inference/default.aspx

2
ответ дан 3 December 2019 в 13:44
поделиться

Компилятор достаточно умен, чтобы определить, что общий тип - это 'int'

1
ответ дан 3 December 2019 в 13:44
поделиться

Компилятор C# поддерживает вывод типов для generics, а также часто встречается при использовании ключевого слова var.

Здесь int выводится из контекста (a и b), поэтому не нужен. Это делает код чище и легче для чтения.

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

7
ответ дан 3 December 2019 в 13:44
поделиться

Компилятор выводит общий тип параметра из типов фактических параметров, которые вы передали.

Эта возможность значительно упрощает вызовы LINQ. (Вам не нужно писать numbers.Select(i => i.ToString()), потому что компилятор выводит int из numbers и string из ToString)

.
5
ответ дан 3 December 2019 в 13:44
поделиться

Компилятор может определить тип T как int, поскольку оба параметра, переданные в What (), имеют тип int. Вы заметите, что многие расширения Linq определены с помощью универсальных шаблонов (как IEnumerable), но обычно используются так, как вы показываете.

2
ответ дан 3 December 2019 в 13:44
поделиться

Он использует вывод типа для общих методов. Обратите внимание, что это изменилось между C # 2 и 3. Например, это не сработало бы в C # 2:

What("hello", new object());

... тогда как в C # 3 (или 4). В C # 2 вывод типа выполнялся для каждого аргумента, и результаты должны были точно совпадать. В C # 3 каждый аргумент предоставляет информацию, которая затем объединяется для вывода аргументов типа. C # 3 также поддерживает многофазный вывод типа, когда компилятор может определить один аргумент типа, а затем посмотреть, есть ли у него дополнительная информация по остальным (например,из-за лямбда-выражений с неявными типами параметров). По сути, он продолжает работать до тех пор, пока не сможет получить больше информации, или не закончит, или пока не увидит противоречивую информацию. Вывод типа в C # не такой мощный, как алгоритм Хиндли-Милнера , но он работает лучше в других отношениях (в частности, он всегда способствует прогрессу).

См. Раздел 7.4.2 спецификации C # 3 для получения дополнительной информации.

7
ответ дан 3 December 2019 в 13:44
поделиться

Это работает, потому что a и b являются целыми числами, поэтому компилятор может вывести аргумент универсального типа для What .

В C # 3 компилятор также может вывести аргумент типа, даже если типы не совпадают, при условии, что расширяющее преобразование имеет смысл. Например, если c было long , то What (a, c) интерпретировалось бы как What .

Обратите внимание: если, скажем, c было строкой , это не сработало бы.

18
ответ дан 3 December 2019 в 13:44
поделиться