Поле, определенное как
const,
ясно указывает, что программист намерен поместить в него постоянное значение. Это плюс. Но оно работает, только если известно значение подобного поля в период компиляции. А что • же делать программисту, когда возникает потребность в поле, чье значение не известно до периода выполнения, но после инициализации не должно меняться? Эта проблема (которая обычно остается нерешенной в большинстве других языков) разрешена разработчиками языка С# с помощью
неизменяемого поля
(read-only field).
Определяя поле с помощью ключевого поля
readonly,
вы можете установить значение поля лишь в одном месте — в конструкторе. После этого поле не могут изменить ни сам класс, ни его клиенты. Допустим, для графического приложения нужно отслеживать разрешение экрана. Решить эту проблему с помощью
const
нельзя, так как до периода выполнения приложение не может определить разрешение экрана у пользователя. Поэтому для этой цели лучше всего использовать такой код:
using System;
class GraphicsPackage {
public readonly int ScreenWidth; public readonly int ScreenHeight;
public GraphicsPackageO {
this.ScreenWidth = 1024;
this.ScreenHeight = 768; } }
/^
class ReadOnlyApp
/
{
public static void Main() {
GraphicsPackage graphics = new GraphicsPackageO; Console.WrlteLine("Ширина = {0}, Высота = {1}", graphics.ScreenWidth, graphics.ScreenHeight); > }
На первый взгляд кажется, что это то, что нужно. Но здесь одна маленькая проблема: определенные нами неизменяемые поля являются полями экземпляра, а значит, чтобы задействовать эти поля, пользователю придется создавать экземпляры класса. Может, это и не проблема, и этот код может даже пригодиться, когда значение неизменяемого поля определяется способом создания экземпляра класса. Но если вам нужна константа, по определению статическая, но инициализируемая в период выполнения? Тогда нужно определить поле с обоими модификаторами —
static
и
readonly,
а затем создать особый — статический — тип конструктора.
Статические конструкторы
(static constructor) используются для инициализации статических, неизменяемых и других полей. Здесь я изменил предыдущий пример так, чтобы сделать поля, определяющие разрешение экрана, статическими и неизменяемыми, а также добавил статический конструктор. Обратите внимание на ключевое слово
static,
добавленное к определению конструктора:
using Systero;
class GraphicsPackage {
public static readonly int ScreenWidth;
public static readonly int ScreenHeight;
static GraphicsPackageO {
// Здесь будет код для расчета разрешения экрана. ScreenWidth = 1024; ScreenHeight = 768; }
}
class ReadOnlyApp
{
public static void MainQ <
Console.WriteLine("Ширина = {0}, Высота = {1}", GraphicsPackage.ScreenWidth, GraphicsPackage.ScreenHeight); } }