Шаргин Александр
Шрифт:
С точки зрения разбухания кода наиболее неблагополучно выглядит класс CDelegateX. Его специализация генерируется для каждой сигнатуры, для которой будет использоваться делегат. Но методы Add, Remove и RemoveAll никак не используют информацию о сигнатуре. То есть для этих методов каждый раз будет генерироваться один и тот же код. Чтобы изменить ситуацию, можно вынести реализацию этих методов в отдельный нешаблонный класс CDelegateImpl. Тогда все специализации шаблона IDelegateX унаследуют эту реализацию, и она останется в программе в единственном экземпляре.
Чтобы реализовать эту идею, для начала разобьём интерфейс IDelegateX на два интерфейса. Базовый, IComparableDelegate, будет "отвечать" за сравнение делегатов. Производный, уже знакомый нам IDelegateX, будет определять дополнительный метод Invoke.
Обратите внимание, что в интерфейсе IComparableDelegate шаблоны не используются. Теперь в терминах этого интерфейса можно реализовать базовый класс CDelegateImpl, который будет отвечать за поддержку списка делегатов. Соответственно, в нём будут реализованы методы Add, Remove и Invoke.
Теперь реализация класса CDelegateX существенно упрощается. В нём останутся только операторы (для которых используется inline-подстановка) и метод Invoke. Только этот метод и будет сгенерирован отдельно для каждой специализации - хороший результат по сравнению с тем, что было раньше. Новая реализация класса CDelegateX будет выглядеть так: