Внутренние абстрактные методы. Зачем им их?
Я делал обзор кода сегодня и наткнулся на старый код, написанный некоторым разработчиком. Это похоже на это
public abstract class BaseControl
{
internal abstract void DoSomething();
}
Если у вас есть производный класс внутри одной сборки, он будет работать
public class DerivedControl : BaseControl
{
internal override void DoSomething()
{
}
}
Но получение базового класса в другой сборке даст ошибку времени компиляции
DerivedControl does not implement inherited abstract member 'BaseControl.DoSomething()
Это заставило меня задуматься. Почему бы кто-нибудь объявить метод как внутренний абстрактный?
Ответы
Ответ 1
Первоначальный программист хотел сделать производный контроль доступным для клиентского кода. Но не позволяйте клиенту унаследовать и возиться с виртуальным методом. Это не плохая идея, обычно легко разбивать базовый класс, переопределяя метод и делая что-то вроде забывания, чтобы вызвать метод базового класса.
Ответ 2
Один очевидный случай - метод получает или возвращает внутренний тип. Например, основные методы классов WPF Transform обрабатывают некоторые внутренние типы взаимодействия, которые WPF не раскрывает как часть своего публичного API. Поскольку подпись включает внутренние типы, метод не может быть общедоступным или защищенным. И все же ясно, что это необходимо (необходимо!) Для различных классов Transform работать полиморфно. Поэтому базовые методы в Transform/GeneralTransform должны быть внутренними.
Другая, но связанная с этим причина заключается в предотвращении внешнего вывода. В конце концов, архитекторы WPF могли бы открыть "безопасную" версию внутренних типов interop в защищенном абстрактном методе, чтобы пользователи могли создавать свои собственные классы Transform. Они не сделали этого, потому что им не хотелось справляться с тем, как люди могут использовать эту возможность, например. создавая неаффинные преобразования. Разрешение внешнего деривации сделало работу других классов в WPF чрезвычайно сложной, поэтому архитекторы решили разрешить только "одобренные" производные классы, сделав абстрактный метод внутренним.
Ответ 3
Моя первоначальная реакция заключалась в том, что нет веской причины, если вы хотите предотвратить внешнее наследование, тогда вы должны пометить внутренний класс. Но это означает, что класс полностью скрыт от других сборок.
Я предполагаю, что этот метод предотвращает внешнее наследование при сохранении видимости.
Ответ 4
Определив метод как внутреннюю абстракцию, вы хотите убедиться, что только класс в той же сборке может иметь свою реализацию для вашего метода.
теперь, если вы распространяете DLL, это позволит избежать наследования и mesup реализации.