Обратите внимание на то, что значения всех констант известны во время компиляции. И действительно, если просмотреть эти константы с помощью ildasm.exe, то вы обнаружите, что их значения будут "жестко" вписаны в компоновочный блок, как показано на рис. 3.8. (Ничего более постоянного получить невозможно!)
Рис. 3.8. Ключевое слово const вписывает "свое" значение прямо в метаданные компоновочного блока
Если нужно сослаться на константу, определенную внешним типом, вы должны добавить префикс имени типа (например, ConstData.Truth), поскольку поля-константы являются
class Program {
public const string BestNhlTeam = "Wild";
static void Main(string[] args) {
// Печать значений констант, определенных другими типами.
Console.WriteLine("Константа Nba: {0}", ConstData.BestNbaTeam);
Console.WriteLine("Константа SimplePI: {0}", ConstData.SimplePI);
Console.WriteLine("Константа Truth: {0}", ConstData.Truth);
Console.WriteLine("Константа Falsity: {0}", ConstData.Falsity);
// Печать значений констант члена.
Console.WriteLine("Константа Nhl: {0}", BestNhlTeam);
// Печать значений констант локального уровня.
const int LocalFixedValue = 4;
Console.WriteLine("Константа Local: {0}", LocalFixedValue);
Console.ReadLine;
}
}
Обратите внимание на то, что для доступа к константам класса ConstData необходимо указать имя типа. Однако класс Program имеет прямой доступ к константе BestNhlTeam, поскольку она была определена в пределах собственной области видимости класса. Константа LocalFixedValue, определенная в Main, конечно же, должна быть доступной только из метода Main.
Исходный код. Проект Constants размещен в подкаталоге, соответствующем главе 3.
Как упоминалось выше, значение, присваиваемое константе, должно быть известно во время компиляции. Но что делать, если нужно создать неизменяемое поле, начальное значение которого будет известно только в
class Tire {
// Поскольку адреса объектов определяются в среде выполнения,
// здесь нельзя использовать ключевое слово 'const.'!
public const Tire Goodstone = new Tire(90); // Ошибка!
public const Tire FireYear = new Tire(100); // Ошибка!
public int manufactureID;
public Tire {}
public Tire(int ID) { manufactureID = ID;}
}
Поля, доступные только для чтения, позволяют создавать элементы данных, значения которых остаются неизвестными в процессе трансляции, но о которых известно, что они никогда не будут изменяться после их создания. Чтобы определить поле, доступное только для чтения, используйте ключевое слово C# readonly.
class Tire {
public readonly Tire GoodStone = new Tire(90);
public readonly Tire FireYear = new Tire(100);
public int manufactureID;
public Tire {}
public Tire (int ID) {manufactureID = ID;}
}
С такой модификацией вы сможете не только выполнить компиляцию, но и гарантировать, что при изменении значений полей GoodStone и FireYear в программе вы получите сообщение об ошибке.
static void Main(string[] args) {
// Ошибка!
// Нельзя изменять значение поля, доступного только для чтения.