jeudi 1 juin 2017

Does using reflection methods such as GetField and GetValue count as "referencing" or "accessing" for the sake of type initialization?

Specifically, are static fields with initializers safe to access using reflection. Maybe it's a dumb question, but I just want concrete clarification; preferably a reference to specification or documentation backing up that using these reflection methods does count as "access" and aren't operating under any special weird rules of their own. (I'm not interested in testing it, I want guarantees.)

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, 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.

Also know about ECMA-334 (C# language specification), Static constructors, section 17.11

The static constructor for a non-generic class executes at most once in a given application domain. The static constructor for a generic class declaration executes at most once for each closed constructed type constructed from the class declaration (§25.1.5). The execution of a static constructor is triggered by the first of the following events to occur within an application domain:

  • An instance of the class is created.
  • Any of the static members of the class are referenced.

If a class contains the Main method (§10.1) in which execution begins, the static constructor for that class executes before the Main method is called. If a class contains any static fields with initializers, those initializers are executed in textual order immediately prior to executing the static constructor (§17.4.5).

And ECMA-335 (CLI specification), Class type definition, part I, section 8.9.5

[...] The semantics of when and what triggers execution of such type initialization methods, is as follows:

  1. A type can have a type-initializer method, or not.
  2. A type can be specified as having a relaxed semantic for its type-initializer method (for convenience below, we call this relaxed semantic BeforeFieldInit).
  3. If marked BeforeFieldInit then the type’s initializer method is executed at, or sometime before, first access to any static field defined for that type.
  4. If not marked BeforeFieldInit then that type’s initializer method is executed at (i.e., is triggered by):
    a. first access to any static field of that type, or
    b. first invocation of any static method of that type, or
    c. first invocation of any instance or virtual method of that type if it is a value type or
    d. first invocation of any constructor for that type.
  5. Execution of any type's initializer method will not trigger automatic execution of any initializer methods defined by its base type, nor of any interfaces that the type implements.

It does sound as if everything is good and well, and I assume it is, I just want to be 100% sure I'm not missing something. (Confirmation basically.)





Aucun commentaire:

Enregistrer un commentaire