Как объявить экземпляр класса как константу в С#?

Мне нужно реализовать это:


static class MyStaticClass
{
  public const TimeSpan theTime = new TimeSpan(13, 0, 0);
  public static bool IsTooLate(DateTime dt)
  {
    return dt.TimeOfDay >= theTime;
  }
}

theTime - постоянная (серьезно:-), как и я, в моем случае было бы бессмысленно читать ее из настроек, например). И я бы хотел, чтобы он был инициализирован один раз и никогда не менялся. Но С#, похоже, не позволяет инициализировать константу функцией (которая является конструктором). Как преодолеть это?

Ответ 1

Использование readonly вместо const может быть инициализировано и не изменено после этого. Это то, что вы ищете?

Ответ 2

Константы должны быть постоянной времени компиляции, и компилятор не может оценить ваш конструктор во время компиляции. Используйте readonly и static конструктор.

static class MyStaticClass
{
  static MyStaticClass()
  {
     theTime = new TimeSpan(13, 0, 0);
  }

  public static readonly TimeSpan theTime;
  public static bool IsTooLate(DateTime dt)
  {
    return dt.TimeOfDay >= theTime;
  }
}

В общем, я предпочитаю инициализировать конструктор вместо прямого назначения, поскольку у вас есть контроль над порядком инициализации.

Ответ 3

С# const не имеет такого же значения, как С++ const. В С#, const используется, чтобы по существу определить псевдонимы к литералам (и поэтому их можно инициализировать только литералами). readonly ближе к тому, что вы хотите, но имейте в виду, что это влияет только на оператор присваивания (объект не является постоянным, если его класс не имеет неизменяемой семантики).

Ответ 4

От эта ссылка:

Константы должны быть типом значений (sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, или bool), перечисление, строка литерал или ссылку на нуль.

Если вы хотите создать объект, это должно быть сделано как static readonly:

static class MyStaticClass
{
  public static readonly TimeSpan theTime = new TimeSpan(13, 0, 0);
  public static bool IsTooLate(DateTime dt)
  {
    return dt.TimeOfDay >= theTime;
  }
}

Ответ 5

public static readonly TimeSpan theTime = new TimeSpan(13, 0, 0);

Ответ 6

Константа представляет собой статический член, значение которого никогда не может измениться. Это означает, что во время компиляции определяется постоянное значение.
С выражением:

    public const TimeSpan theTime = new TimeSpan(13, 0, 0);

Нарушаются две аксиомы постоянных полей:

  • Только встроенные типы С# (исключая System.Object) могут быть объявлены как const.
  • Значение Iniatialization должно оцениваться во время компиляции

В вопросе используется тип TimeSpan, который не является встроенным (предопределенным) типом. Это означает, что компилятор csc.exe не может его распознать.
Если вы используете встроенный тип С# (например, String), и вы хотите инициализировать константный элемент значением времени компиляции, вы все равно получите ошибку: например,

 public const string MyNumber = SetMyString();
 private string SetMyString()
 {
  return "test";
 }

Решая проблему, вы можете объявить участника:

static readonly

если вы хотите объявить поле только один раз во время выполнения:

public static readonly string MyNumber = SetMyString();
private static string SetMyString()
{
 return "test";
}

Ответ 7

Вы можете использовать ключевое слово readonly:

Если объявление поля содержит модификатор readonly, присваивания поля, введенные декларацией, могут возникать только как часть объявления или в конструкторе того же класса.

Пример (скопирован со связанной страницы MSDN):

class Age
{
    readonly int _year;
    Age(int year)
    {
        _year = year;
    }
    void ChangeYear()
    {
        //_year = 1967; // Compile error if uncommented.
    }
}