Он не вызывает «специализированный», потому что компилятор выбирает, какой метод вызывать, когда программа (в данном случае это функция Go
) скомпилирована , не при запуске.
Когда компилятор компилирует функцию Go
, единственная информация, которую он имеет, - это наличие некоторого объекта типа T
. Он не имеет ни малейшего представления о том, что в какой-то более поздний момент вы можете снабдить его объектом типа MyBase
. Единственная опция, которую он имеет, - это выбрать перегрузку Foo<T>
, и она заполняет ее скомпилированной программой.
Если вы хотите, чтобы приложение выбирало перегрузки во время выполнения и выбирало наилучшую перегрузку, глядя на объект во время работы приложения, это называется «динамическая диспетчеризация» и используется только динамическими языками, такими как Ruby, Python, PHP и т. Д.
C # 3 полностью статичен и не поддерживает это. Вам нужно написать в своем коде оператор if, чтобы проверить тип, если вы хотите, чтобы он работал таким образом.
C # 4, с другой стороны, имеет некоторую динамическую поддержку. Если бы вы писали этот код на C # 4, вы могли бы объявить функцию Go следующим образом:
public void Go<T> (IEnumerable<dynamic> items)
Тогда он будет использовать динамическую диспетчеризацию во время выполнения, чтобы выбрать, какая перегрузка вызывается, и вызовет перегрузку, специализированную для принятия MyBase