This is an example of a possible difference:
class SimpleClass
{
static readonly long A = DateTime.Now.Ticks;
static readonly long B = DateTime.Now.Ticks;
static SimpleClass()
{
}
}
A
and B
are not guaranteed to be the same value, though if you were to write it in the constructor, you could guarantee it:
class SimpleClass
{
static readonly long A;
static readonly long B;
static SimpleClass()
{
var ticks = DateTime.Now.Ticks;
A = ticks;
B = ticks;
}
}
In addition, order matters for instantiation of static members.
According to ECMA-334 regarding static field initialization:
The static field variable initializers of a class declaration
correspond to a sequence of assignments that are executed in the
textual order in which they appear in the class declaration. If a
static constructor (§17.11) exists in the class, execution of the
static field initializers occurs immediately prior to executing that
static constructor. Otherwise, the static field initializers are
executed at an implementation-dependent time prior to the first use of
a static field of that class
So, we can write something like this:
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;
}
}
Here, A
is guaranteed to be assigned before B
. In this example, A
will be 1
, and B
will be 2
. We can guarantee that A
< B
(assuming the identity does not overflow and there's no issues with threading). Now, if we re-order the fields:
public static readonly long B = IdentityHelper.GetNext();
public static readonly long A = IdentityHelper.GetNext();
The functionality changes. Thus, we've created a side-effect which is not immediately clear simply by re-ordering the fields definitions.
A more likely scenario is, we may want to do this:
class SimpleClass
{
public static readonly long A = IdentityHelper.GetExpensiveResult().A;
public static readonly long B = IdentityHelper.GetExpensiveResult().B;
static SimpleClass()
{
}
}
Here, we're unable to share GetExpensiveResult()
between the fields.