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 not guaranteed the same value, although 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 an instance of static elements.
According to ECMA-334 regarding static field initialization:
The initializers of the static variable of the class declaration field correspond to the sequence of assignments that are executed in the text order in which they are displayed in the class declaration. If a static constructor (ยง17.11) exists in the class, the execution of the initializers of the static field occur immediately before the execution of this static constructor. Otherwise, the initializers of the static field executed in the implementation-dependent time until the first use of the static field of this 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 guaranteed to be assigned to B In this example, A will be 1 and B will be 2 . We can guarantee that A < B (provided that the identifier is not overflowing and there are no problems with stream processing). Now, if we reorder the fields:
public static readonly long B = IdentityHelper.GetNext(); public static readonly long A = IdentityHelper.GetNext();
Functionality is changing. Thus, we created a side effect that is not immediately cleared simply by redefining the field definitions.
A more likely scenario, we can do this:
class SimpleClass { public static readonly long A = IdentityHelper.GetExpensiveResult().A; public static readonly long B = IdentityHelper.GetExpensiveResult().B; static SimpleClass() { } }
Here we cannot share GetExpensiveResult() between fields.