Константы классы
Кроме полей класс может определять для хранения данных константы. В отличие от полей их значение устанавливается один раз непосредственно при их объявлении и впоследствии не может быть изменено. Кроме того, константы хранят некоторые данные, которые относятся не к одному объекту, а ко всему классу в целом. И для обращения к константам применяется не имя объекта, а имя класса:
Person tom = new Person();
tom.name = "Tom";
tom.Print(); // Person: Tom
Console.WriteLine(Person.type); // Person
// Person.type = "User"; // !Ошибка: изменить константу нельзя
class Person
{
public const string type = "Person";
public string name = "Undefined";
public void Print() => Console.WriteLine($"{type}: {name}");
}
Здесь в классе Person определена константа type, которая хранит название класса:
public const string type = "Person";Название класса не зависит от объекта. Мы можем создать много объектов Person, но название класса от этого не должно измениться - оно относится ко всем объектам Person и не должно меняться. Поэтому название типа можно сохранить в виде константы.
Стоит отметить, что константе сразу при ее определении необходимо присвоить значение.
Подобно обычным полям мы можем обращаться к константам класса внутри этого класса. Например, в методе Print значение константы выводится на консоль.
Однако если мы хотим обратиться к константе вне ее класса, то для обращения необходимо использовались имя класса:
Console.WriteLine(Person.type); // PersonТаким образом, если необходимо хранить данные, которые относятся ко всему классу в целом, то можно использовать константы.
Поля для чтения и модификатор readonly
Поля для чтения представляют такие поля класса или структуры, значение которых нельзя изменить. Таким полям можно присвоить значение либо при непосредственно при их объявлении, либо в конструкторе. В других местах программы присваивать значение таким полям нельзя, можно только считывать их значение.
Поле для чтения объявляется с ключевым словом readonly:
Person tom = new Person("Tom");
Console.WriteLine(tom.name);
//tom.name = "Sam"; // !Ошибка: нельзя изменить
class Person
{
public readonly string name = "Undefined"; // можно так инициализировать
public Person(string name)
{
this.name = name; // в конструкторе также можно присвоить значение полю для чтения
}
public void ChangeName(string otherName)
{
//this.name = otherName; // так нельзя
}
}
Здесь поле name хранит имя пользователя и представляет поле для чтения. Ему можно присвоить значение непосредственно при объявлении:
public readonly string name = "Undefined";Либо можно присвоить значение в конструкторе
public Person(string name)
{
this.name = name;
}
В остальных местах программы, в том числе в самом классе Person присвоить значение полю для чтения нельзя.
Сравнение констант
Константы должны быть определены во время компиляции, а поля для чтения могут быть определены во время выполнения программы.
Соответственно значение константы можно установить только при ее определении.
Поле для чтения можно инициализировать либо при его определении, либо в конструкторе класса.
Константы не могут использовать модификатор static, так как уже неявно являются статическими. Поля для чтения могут быть как статическими, так и не статическими.
Структуры для чтения
Кроме полей для чтения в C# можно определять структуры для чтения. Для этого они предваряются модификатором readonly:
readonly struct Person { }
Особенностью таких структур является то, что все их поля должны быть также полями для чтения:
readonly struct Person
{
public readonly string name;
public Person(string name)
{
this.name = name;
}
}
То же самое касается и свойств, которые должны быть доступны только для чтения:
readonly struct Person
{
public readonly string Name { get; } // указывать readonly необязательно
public int Age { get; } // свойство только для чтения
public Person(string name, int age)
{
Name = name;
Age = age;
}
}
Дополнительные материалы