Это пример возможного различия:
class SimpleClass
{
static readonly long A = DateTime.Now.Ticks;
static readonly long B = DateTime.Now.Ticks;
static SimpleClass()
{
}
}
A
и B
не гарантируется иметь то же значение, хотя, если вы напишете его в конструкторе, вы можете это гарантировать:
class SimpleClass
{
static readonly long A;
static readonly long B;
static SimpleClass()
{
var ticks = DateTime.Now.Ticks;
A = ticks;
B = ticks;
}
}
Кроме того, заказывает вопросы для создания статических элементов.
Согласно ECMA-334 относительно статической инициализации поля:
статического поля инициализаторы переменной класса декларации соответствует последовательностям заданий, которые выполняются в текстовом порядке, в котором они появляются в объявление класса. Если в классе существует статический конструктор (§17.11), выполнение статических инициализаторов статического поля происходит непосредственно перед выполнением статического конструктора . В противном случае, статические поля Инициализаторов выполняются на время, зависящая от реализации до первого использования статического поля этого класса
Таким образом, мы можем написать что-то вроде этого:
class SimpleClass
{
public static readonly long A = IdentityHelper.GetNext();
public static readonly long B = IdentityHelper.GetNext();
static SimpleClass()
{
}
}
public static class IdentityHelper
{
public static int previousIdentity = 0;
public static int GetNext()
{
return ++previousIdentity;
}
}
Здесь A
гарантированно назначается до B
. В этом примере A
будет 1
, а B
будет 2
. Мы можем гарантировать, что A
< B
(при условии, что идентификатор не переполняется, и нет проблем с потоками). Теперь, если мы изменить порядок полей:
public static readonly long B = IdentityHelper.GetNext();
public static readonly long A = IdentityHelper.GetNext();
Функциональность изменения. Таким образом, мы создали побочный эффект, который не сразу становится понятным просто путем переопределения определений полей.
Более вероятный сценарий, мы хотим сделать это:
class SimpleClass
{
public static readonly long A = IdentityHelper.GetExpensiveResult().A;
public static readonly long B = IdentityHelper.GetExpensiveResult().B;
static SimpleClass()
{
}
}
Здесь мы не можем разделить GetExpensiveResult()
между полями.
Это не статический вопрос, вопрос действительно и для нестатической инициализации. –
Возможный дубликат [Инициализировать поля класса в конструкторе или в объявлении?] (Http://stackoverflow.com/questions/24551/initialize-class-fields-in-constructor-or-at-declaration) –
@CyrilGandon Это не обман - это о статических конструкторах, которые не принимают параметры. Попробуйте удалить тег dupe. –