const
і readonly
подібні, але вони не зовсім однакові.
const
Поле є константою часу компіляції, а це означає , що це значення може бути обчислено під час компіляції. readonly
Поле дозволяє встановлювати додаткові сценарії , в яких будь - то код повинен бути запущений під час будівництва цього типу. Після побудови readonly
поле не може бути змінено.
Наприклад, const
члени можуть бути використані для визначення членів типу:
struct Test
{
public const double Pi = 3.14;
public const int Zero = 0;
}
Оскільки значення типу 3.14 і 0 є константами часу компіляції. Однак розглянемо випадок, коли ви визначаєте тип і хочете надати деякі його попередні файли. Наприклад, ви можете визначити клас кольорів та надати "константи" для таких кольорів, як чорний, білий та ін. Це неможливо зробити з членами const, оскільки права сторона не є константами часу компіляції. Це можна зробити за допомогою регулярних статичних членів:
public class Color
{
public static Color Black = new Color(0, 0, 0);
public static Color White = new Color(255, 255, 255);
public static Color Red = new Color(255, 0, 0);
public static Color Green = new Color(0, 255, 0);
public static Color Blue = new Color(0, 0, 255);
private byte red, green, blue;
public Color(byte r, byte g, byte b) => (red, green, blue) = (r, g, b);
}
Але тоді немає нічого, що не дозволяє клієнтові Color не спілкуватися з ним, можливо, замінюючи значення Чорно-Білі. Зайве говорити, що це може викликати побоювання у інших клієнтів класу Color. Функція "лише для читання" стосується цього сценарію.
Просто вводячи readonly
ключове слово в декларації, ми зберігаємо гнучку ініціалізацію, не дозволяючи клієнтському коду не змінюватися.
public class Color
{
public static readonly Color Black = new Color(0, 0, 0);
public static readonly Color White = new Color(255, 255, 255);
public static readonly Color Red = new Color(255, 0, 0);
public static readonly Color Green = new Color(0, 255, 0);
public static readonly Color Blue = new Color(0, 0, 255);
private byte red, green, blue;
public Color(byte r, byte g, byte b) => (red, green, blue) = (r, g, b);
}
Цікаво відзначити, що члени const завжди є статичними, тоді як член, що читає лише, може бути статичним чи ні, як звичайне поле.
Можна використовувати одне ключове слово для цих двох цілей, але це призводить до проблем з версіями або до продуктивності. Припустимо на мить, що для цього ми використовували одне ключове слово (const), і розробник написав:
public class A
{
public static const C = 0;
}
і інший розробник написав код, який спирався на A:
public class B
{
static void Main() => Console.WriteLine(A.C);
}
Тепер, чи може сформований код покладатися на той факт, що AC - константа часу компіляції? Тобто, чи може використання змінного струму просто замінити значенням 0? Якщо ви скажете "так" цьому, то це означає, що розробник A не може змінити спосіб ініціалізації AC - це пов'язує руки розробника з A без дозволу.
Якщо ви скажете "ні" на це питання, важлива оптимізація пропущена. Можливо, автор A впевнений, що зміна струму завжди буде дорівнює нулю. Використання const і readonly дозволяє розробнику A вказати наміри. Це сприяє кращій поведінці версій, а також кращій роботі.
static readonly
: спробуйте використовувати const всередині,IEnumerator
який викликає неможливість повторної перевірки,yield
і ви отримаєте жахливу "внутрішню помилку компілятора" . Я не перевіряв код за межами Unity3D, але я вірю, що це моно або .NET- помилка . Але це питання # .