У меня есть более 30 классов, которые используются в качестве общего параметра для дочернего класса. здесь TKind может быть любым классом из набора около 30 классов.
Код: Выделить всё
internal sealed class Child : Base
{
public override void SupplyTo(IBuilder builder)
{
builder.AddPart((dynamic)this);
}
}
В сборщике есть перегрузка AddPart для всех 30 возможных случаев.
Это не скомпилируется:
потому что это универсальный тип, и компилятор не может разрешить перегрузку метода. потому что он не знает, предусмотрена ли перегрузка для этого универсального типа или нет.
но это скомпилируется, поскольку мы используем динамическую отправку, а перегрузка метода разрешается во время выполнения.
Меня беспокоит производительность. Перегрузки AddPart могут вызываться тысячи раз. оптимизирует ли компилятор динамическую часть после того, как он впервые разрешает перегрузку для каждого универсального типа? знает ли он, что this всегда будет одного и того же типа в этом контексте?
только первый вызов для каждого универсального типа будет дорогостоящим вызовом, а остальная часть вызовы будут подобны прямому вызову перегрузки метода?
Давайте приведем пример.
первый подход:
Код: Выделить всё
foreach(Base item in items)
{
builder.AddPart((dynamic)item); // dynamic dispatch
}
Я предполагаю, что здесь компилятор не может оптимизировать динамический вызов, поскольку элемент может быть чем угодно.
второй подход:
Код: Выделить всё
foreach(Base item in items)
{
item.SupplyTo(builder); // double dispatch
}
но в приведенном выше примере мы используем шаблон посетителя, и в каждом универсальном классе это всегда одного и того же типа. значит, во втором подходе должны быть некоторые оптимизации?
Подробнее здесь:
https://stackoverflow.com/questions/441 ... r-generics