constи readonlyпохожи, но они не совсем одинаковы.
constПоле является константой времени компиляции, а это означает , что это значение может быть вычислено во время компиляции. readonlyПоле позволяет устанавливать дополнительные сценарии , в которых какой - то код должен быть запущен во время строительства этого типа. После строительства readonlyполе не может быть изменено.
Например, constчлены могут использоваться для определения таких членов, как:
struct Test
{
public const double Pi = 3.14;
public const int Zero = 0;
}
Так как значения как 3.14 и 0 являются константами времени компиляции. Тем не менее, рассмотрим случай, когда вы определяете тип и хотите предоставить некоторые заранее созданные экземпляры этого типа. Например, вы можете определить класс Color и предоставить «константы» для общих цветов, таких как черный, белый и т. Д. Это невозможно сделать с помощью константных членов, поскольку правые части не являются константами времени компиляции. Это можно сделать с помощью обычных статических членов:
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 изменить его, возможно, путем замены значений Black и White. Излишне говорить, что это вызвало бы смятение у других клиентов класса 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), и разработчик написал:
public class A
{
public static const C = 0;
}
и другой разработчик написал код, который опирался на A:
public class B
{
static void Main() => Console.WriteLine(A.C);
}
Теперь, может ли генерируемый код опираться на тот факт, что AC является константой времени компиляции? Т.е. можно ли просто заменить использование AC значением 0? Если вы скажете «да» на это, то это означает, что разработчик A не может изменить способ инициализации AC - это связывает руки разработчика A без разрешения.
Если вы ответите «нет» на этот вопрос, то пропустите важную оптимизацию. Возможно, автор A уверен, что AC всегда будет нулевым. Использование const и readonly позволяет разработчику A указать намерение. Это улучшает поведение при управлении версиями, а также повышает производительность.
static readonly: попробуйте использовать const внутри,IEnumeratorкоторый вызовет необратимое,yieldи вы получите страшную «Внутреннюю ошибку компилятора» . Я не тестировал код вне Unity3D, но я уверен, что это ошибка в моно или .NET . Это C # вопрос , тем не менее.