What do I really want to know, which reflection methods will initiate type initialization? This is a little incomprehensible to me. In particular, will the two mentioned methods GetField and GetValue initialize the start type if they apply to static fields? I have already tried to understand this issue, and, as I understand it, the execution of actions, such as links or access to static fields, will lead to initialization of the type of all static fields. Below I quoted sections of the specification that, in my opinion, are relevant, but the use of formulations such as “summarizing” and “access” is exactly the place where my doubts arise:
What actions really qualify as “access”?
Does FieldInfo metadata get for a field as a “link” or “access” to a field?
Please help me find the relevant parts of the specifications, so I know that my code * is safe and specified. compatible and not just “working” due to some undocumented implementation details or because the planets are in the correct order.
* My code is being tested, but relies on type initialization behavior. My code is not shown here because it is verbose and the question is not that I just want “your code to look normal”, but I want to know how and why it is that I can evaluate whether my code is a specification . or (I believe this is consistent) about what changes I can and cannot do without having to ask a new question every time I do it.
So far, I am aware of the following parts of the specifications that use the above terms “links” and “access”:
I know about ECMA-334 (C # Language Specification), static field initialization, section 17.4.5.1
If a static constructor (§17.11) exists in the class, the execution of the initializers of the static field occurs immediately before the execution of this static constructor. Otherwise, the initializers of the static field are executed in an implementation-dependent time until the first use of the static field of this class.
Also Know About ECMA-334 (C # Language Specification), Static Constructors, Section 17.11
A static constructor for a non-generic class is executed no more than once in a given application domain. The static constructor for declaring a universal class is executed no more than once for each closed constructed type built from the class declaration (§ 25.1.5). The execution of the static constructor is triggered by the first of the following events that must occur in the application domain:
- An instance of the class is created.
- A reference to any of the static members of the class.
If the class contains the Main method (§10.1) in which execution starts, the static constructor for this class is executed before the Main method is called. If the class contains any static fields with initializers, then initializers are executed in textual order immediately before the execution of the static constructor (§17.4.5).
And more relevant is ECMA-335 (CLI Specification), Class Type Definition, Part I, Section 8.9.5
[...] The semantics of when and what triggers the execution of such type initialization methods is as follows:
- A type can have an initializer type or not.
- A type can be defined as having relaxed semantics for its type initializer method (for convenience, we call this relaxed semantics BeforeFieldInit below).
- If the value BeforeFieldInit is checked, then the type initialization method is launched, or ever before, that has access to any static field defined for this type.
- If the BeforeFieldInit value is not specified, then this type of initialization method is executed (i.e., launched):
but. first access to any static field of this type or
b. first call of any static method of this type or
from. the first call of any instance or virtual method of this type if it is a value type or
The first call of any constructor for this type. - Execution of any initializer method of any type will not initiate the automatic execution of any initialization methods defined by its base type and any interfaces that the type implements.
Related MSDN Links:
Type.GetField Method
FieldInfo Class
FieldInfo.GetValue Method