Как объявить экземпляр класса как константу в C #? - PullRequest
35 голосов
/ 03 июня 2011

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

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

theTime - это константа (серьезно :-), как и π, в моем случае было бы бессмысленно читать ее, например, из настроек И я бы хотел, чтобы он был инициализирован один раз и никогда не менялся.

Но C # не позволяет инициализировать константу с помощью функции (которая является конструктором). Как это побороть?

Ответы [ 7 ]

59 голосов
/ 03 июня 2011

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

Пример кода:

static class MyStaticClass
{
    public static readonly TimeSpan theTime;
    static MyStaticClass
    {
        theTime = new TimeSpan(13, 0, 0)
    }
}
37 голосов
/ 03 июня 2011

Константы должны быть постоянными времени компиляции, и компилятор не может оценить ваш конструктор во время компиляции.Используйте 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;
  }
}

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

10 голосов
/ 03 июня 2011

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

7 голосов
/ 03 июня 2011

С эта ссылка :

Константы должны иметь тип значения (sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, десятичное или 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;
  }
}
4 голосов
/ 03 июня 2011
public static readonly TimeSpan theTime = new TimeSpan(13, 0, 0);
1 голос
/ 16 сентября 2016

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

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

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

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

В вопросе используется тип TimeSpan, который не является встроенным (предопределенным) Типом.Это означает, что компилятор csc.exe не может его распознать.Если вы используете встроенный тип C # (например, 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";
}
0 голосов
/ 09 июня 2015

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

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

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

class Age
{
    readonly int _year;
    Age(int year)
    {
        _year = year;
    }
    void ChangeYear()
    {
        //_year = 1967; // Compile error if uncommented.
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...