Что делают общие методы С# для не-общего класса?

Если у меня есть класс вроде: -

static class Foo {
   public static void Bar<T>(T item) { Console.WriteLine(item.ToString(); }
}

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

Foo.Bar("Hello");
Foo.Bar(123);
Foo.Bar(new Employee("Isaac"));

Я широко (думаю!) Я понимаю, что reification, т.е., если вы делаете разные типы общего класса, например.

List<Int32>
List<String>
List<Employee>

и т.д.. то во время компиляции (или времени выполнения?) мы получаем три фактических конкретных типа, по одному для каждого заданного общего аргумента. То же самое относится к вызовам метода в моем первом примере, то есть у нас будет еще один класс Foo, но три метода reified Bar, один для String, Int32 и Employee?

Ответ 1

Здесь разворачивается различие между шаблонами С++ и обобщенными С#.

В С++ шаблоны вызывают создание нового метода для каждого типа, с которым он используется. Однако в С# код в методе создается только один раз. Тот же код запускается, если вы вызываете его с параметром типа int, string или object.

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

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