внутренние абстрактные методы. Почему у кого-либо были бы они?

Я делал некоторый обзор кода сегодня и столкнулся со старым кодом, написанным некоторым разработчиком. Это проходит примерно так

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()

Это получило меня взгляды. Почему кто-либо объявил бы метод как внутренний краткий обзор?

14
задан AGB 25 May 2016 в 03:08
поделиться

4 ответа

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

12
ответ дан 1 December 2019 в 13:21
поделиться

Один очевидный случай - когда метод получает или возвращает внутренний тип. Например, основные методы классов WPF Transform обрабатывают некоторые внутренние типы interop, которые WPF не раскрывает как часть своего публичного API. Поскольку сигнатура включает внутренние типы, метод не может быть ни публичным, ни защищенным. И все же очевидно, что для различных классов Transform уместно (необходимо!) работать полиморфно. Поэтому базовые методы в Transform/GeneralTransform должны быть внутренними.

Другая, но связанная с этим причина - предотвращение внешней деривации. В конце концов, архитекторы WPF могли бы раскрыть "безопасную" версию внутренних взаимодействующих типов в защищенном абстрактном методе, чтобы пользователи могли создавать свои собственные классы Transform. Они не сделали этого, потому что не хотели иметь дело с тем, как люди могут использовать эту возможность, например, создавая неаффинные преобразования. Разрешение внешней производности сделало бы работу других классов в WPF чрезвычайно сложной, поэтому архитекторы решили разрешить только "одобренные" производные классы, сделав абстрактный метод внутренним.

6
ответ дан 1 December 2019 в 13:21
поделиться

Моей первоначальной реакцией было то, что нет никакой веской причины, если вы хотите предотвратить внешнее наследование, то вы должны пометить класс как внутренний. Но это означает, что класс будет полностью скрыт для других сборок.

Я полагаю, что этот метод предотвращает внешнее наследование, сохраняя видимость.

1
ответ дан 1 December 2019 в 13:21
поделиться

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

теперь если вы распространяете dll от него, это позволит избежать наследования и затирания реализации клиентом.

0
ответ дан 1 December 2019 в 13:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: