Наверное у каждого во время работы или изучения новой технологии (языка) возникают вопросы вида «А что если...?», «А можно ли...?» и т.д. У меня они тоже постонно возникают, поэтому вашему вниманию 9 вопросов по C#, ответы на которые могут понадобиться наверное только чтобы успокоить свой пытливый разум.
- Можно ли сделать абстрактным getter или setter?
Нет. Но абстрактным можно сделать всё свойство. При этом класс должен быть абстрактным. Модификатором доступа в этом случае может быть только public или protected (private использовать нельзя). Можно ограничить доступ getter-a или setter-а до protected, если свойство объявлено с модификатором доступа public.
Другими словами можно так:
abstract class User { abstract public string Name { get; set; } }
или так
abstract class User { abstract protected string Name { get; set; } }
и даже так:
abstract class User { abstract public string Name { get; protected set; } }
но не так
abstract class User { abstract private string Name { get; set; } }
или так
abstract class User { abstract public string Name { get; private set; } }
и это логично, учитывая что виртаульные (абстрактные) члены могу могут быть только public или private.
- Можно ли сделать неявную реализацию метода сразу для двух или более интерфейсов?
Да, можно. Более того, метод в таком случае обязан быть объявлен с модификатором доступа public. Иначе нужно выполнять явную реализацию для каждого метода. - Доступен ли метод объявленный в интерфейсе и реализоанный в базовом классе через ссылку на производный класс?
Всё зависит от того, как выполнена реализация метода в базовом классе (явно или неявно).
Рассмотрим пример:
interface IA { void make(); } class Base : IA { void IA.make() { Console.WriteLine("Base implementation."); } } class Derived: Base { }
при такой (явной) реализации метод make будет доступен только ссылку типа интерфейса (IA), но не будет доступен через ссылки типа Base или Derived. В тоже время при такой реализации (неявной):
interface IA { void make(); } class Base : IA { public void make() { Console.WriteLine("Base implementation."); } } class Derived: Base { }
метод make будет доступен через ссылки любого типа (IA, Base или Derived).
- Можно ли создать объект класса, в котором не реализовано свойство или метод интерфейса?
Нет. Все свойства и методы должны получить реализации, причём именно в базовом в том классе, что наследует интерфейс. Поэтому нельзя создать даже абстрактный класс и реализовать оставшиеся свойства и методы в производном. - Доступны ли наследование и виртаулизация для структур?
Виртуальные методы и свойства недоступныдля структур. Структуры не могут быть базовыми классами или наследовать другие классы. Структуры не могут быть абстрактными. Структуры не могут иметь явного конструктора экземпляра, но могут иметь явный статический конструктор. Структуры могут реализовывать интерфейсы. - Могут ли в одном классе быть явная и неявная реализация метода интерфейса?
Да, могут. Например:
interface IA { void make(); } class Base : IA { void IA.make(){ Console.WriteLine("Interface implementation."); } public void make() { Console.WriteLine("Base implementation."); } }
в таком случае будет вызвана явная реализация. Если явная реализация отсутствует — вызывается неявная. Если отсутствует и она — компиляция будет выполнена с ошибкой.
- Можно ли разделить объявление свойства?
Нет. Даже для partial классов. Другими словами такой код не скомпилируется:partial class Base{ public string Name { get; } } partial class Base{ public string Name { set; } }
- Можно ли изменить модификатор доступа виртуального метода в призводном классе?
Нет. Но можно использаяnew virtual
разорвать цепочку виртуализации и начать новую с новым модификатором доступа.
- Можно ли сделать метод интерфейса виртуальным?
Методы объявленные в интерфейсе не являются виртуальными. Однако, если реализацию, причём только неявную, пометить как virtual (явную реализацию пометить виртуальной нельзя), то даже через ссылку типа интерфейса вызов метода будет аналогичным вызову виртуального метода. То есть виртуальные метода будут работать как обычно. Минусом такого подхода является как минимум то, что нужно в каждом базовом классе (реализующем интерфейс) помечать метод виртуальным.
На данный момент всё. Если у есть свои примеры таких вопросов — буду рад прочитать их в комментариях. Примеры тестировались в .NET Core.
Спасибо за внимание!
Автор: незнакомец