C# для профессионалов. Том II
Шрифт:
На самом деле в C++, даже если не требуется инициализировать статическое поле, необходимо включить эту инструкцию, чтобы избежать ошибки компоновки. В противоположность этому C# не ожидает подобной инструкции, так как в C# переменные объявляются только в одном месте:
Конструкторы
Синтаксис объявления конструкторов в C# такой же, как синтаксис для встраиваемых
Как и в C++, можно определить столько конструкторов, сколько потребуется, при условии, что они получают различное число или типы параметров. (Отметим, что, как и в методах, параметры по умолчанию не допускаются, необходимо моделировать это с помощью нескольких перезагружаемых версий.)
Для производных классов иерархии конструкторы действуют в C# по сути таким же образом, как и в C++. По умолчанию конструктор на вершине иерархии (это всегда
Статические конструкторы
C# допускает также концепцию статического конструктора, который выполняется только один раз и может использоваться для инициализации статических переменных. Концепция не имеет прямого эквивалента в C++.
Статические конструкторы очень полезны тем, что позволяют инициализировать статические поля с помощью значений, которые определяются во время выполнения (например, они могут задаваться значениями которые считываются из базы данных). Такой результат возможен в C++, но требует определенной работы, и решение обычно выглядит беспорядочным. Наиболее общий подход должен иметь функцию, которая обращается к статическим переменным членам, и функция будет реализована таким образом, что она задает значение переменной при первом вызове.
Отметим, что статический конструктор не имеет спецификатора доступа, он не объявляется как открытый, закрытый или как-нибудь еще. Спецификатор доступа не будет иметь смысла, так как статический конструктор вызывается только средой выполнения .NET, когда загружается определение класса. Он не может вызываться никаким другим кодом C#.
C# не задает точно, когда будет выполнен статический конструктор, за исключением только того, что это произойдет после инициализации всех статических полей, но перед тем, как будет создан какой-либо объект класса, или там, где статические методы класса реально используются.
Конструкторы по умолчанию
Как и в C++, классы C# обычно имеют конструктор по умолчанию без параметров, который просто вызывает конструктор без параметров непосредственного базового класса, а затем инициализирует все поля их параметрами по умолчанию. Так же как в C++, компилятор будет создавать этот конструктор по умолчанию, только если в коде явно не предоставлен никакой другой конструктор. Если какие-либо конструкторы присутствуют в определении класса, то в этом случае будут
доступны только эти конструкторы, независимо от того, есть или нет среди них конструктор без параметров.Как и в C++ можно обойтись без создания экземпляров класса, объявляя закрытый конструктор единственным.
Это также не позволяет создавать экземпляры любых производных классов. Однако, если класс или методы в нем объявлены абстрактными, то нельзя создать экземпляр этого класса, причем не обязательно производного класса.
Списки инициализации конструктора
Конструкторы C# могут иметь элементы, которые выглядят как списки инициализации конструктора C++. Однако в C# такой список содержит только максимум один член и называется инициализатором конструктора. Элемент в инициализаторе должен быть либо конструктором непосредственного базового класса, либо другим конструктором того же класса. Синтаксис этих двух вариантов использует ключевые слова
Если явно не задан никакой список инициализации конструктора, то компилятор будет неявно использовать список из элемента
В отличие от C++ нельзя поместить переменные члены в список инициализации конструктора. Однако это только вопрос синтаксиса, так как эквивалент C# должен отметить свои начальные значения в определении класса.
Более серьезным различием является тот факт, что можно поместить только один иной конструктор в список. Это влияет на способ разработки конструкторов, хотя несомненно полезно, так как заставляет использовать хорошо определенную и эффективную парадигму организации конструкторов. Эта парадигма указана в приведенном выше коде. Все конструкторы следуют единому порядку, в котором выполняются различные конструкторы.
Деструкторы
C# реализует отличную от C++ модель программирования деструкторов. Это связано с тем, что механизм сборки мусора в C# предполагает следующее:
□ Существует меньшая необходимость в деструкторах, так как динамически распределенная память будет удаляться автоматически.
□ Так как невозможно предсказать, когда сборщик мусора реально разрушит заданный объект, то если для класса предоставляется деструктор, невозможно предсказать в точности, когда этот деструктор будет выполнен.