Можно ли объявлять приватные методы в интерфейсе в новых версиях C# и как это реализовано
Что проверяют
Знаете ли вы про реализации по умолчанию в интерфейсах из C# 8 и понимаете ли, что приватный метод интерфейса виден только самому интерфейсу. Следом обычно спрашивают, чем интерфейс с реализацией теперь отличается от абстрактного класса.
Как отвечать
Да, начиная с C# 8 интерфейс может содержать члены с телом, и вместе с этим появились модификаторы доступа внутри интерфейса:
- метод по умолчанию: публичный член с реализацией. Класс может его не реализовывать, тогда работает версия интерфейса;
private: обязательно с телом, вызывается только из других членов этого же интерфейса. Это способ вынести общий код из нескольких методов по умолчанию;static: статические методы и поля, в том числе приватные;protected: виден в интерфейсах-наследниках, а через реализующий класс его не вызвать.
Как это устроено. Реализацию хранит сам тип интерфейса, а поддерживать это должна среда выполнения: фича работает на .NET Core 3.0 и новее, из .NET Standard доступна с версии 2.1, а .NET Framework её не умеет. Состояния у интерфейса по-прежнему нет: экземплярных полей объявить нельзя, приватный метод работает только через другие члены и this.
Стоит добавить про вызов. Метод по умолчанию не становится членом класса: через переменную типа класса его не видно, объект нужно привести к интерфейсу. У структуры такой вызов через интерфейс ещё и упаковывает значение.
Где это полезно: добавить метод в публичный интерфейс библиотеки, не ломая чужие реализации, и не дублировать проверки в нескольких методах по умолчанию. Для полноты можно упомянуть static abstract члены из C# 11, на которых построена generic math.
Где спотыкаются
Утверждают, что класс-реализация может вызвать приватный метод интерфейса. Такой код не скомпилируется: для класса этого метода не существует.
Путают с абстрактным классом. Интерфейс не хранит состояние и не имеет конструкторов, так что заменить базовый класс с полями он не может.
Забывают про платформу. В проекте на .NET Framework 4.8 компилятор выдаст ошибку, что целевая среда выполнения не поддерживает реализацию в интерфейсах, даже если поднять версию языка.