In accordance with this question, it must be guaranteed that the static fields that I use are initialized:
10.4.5.1 Initialization of a static field:
The initializers of a static variable of a class field correspond to the sequence of assignments executed in the text order in which they appear in the class declaration. If a static constructor (Section 10.11) exists in the class, the execution of the static field is done by initializers immediately before the execution of this static constructor. Otherwise, the static field initializers are executed at the implementation-dependent time until the first use of the static field of this class .
I came across a strange case when this does not seem to be true. I have two classes that are circularly dependent on each other and where a NullReferenceException .
I was able to reproduce this problem in the following simplified example, look:
public class SessionManager {
The problem remains if you uncomment the static constructors as suggested in another question . Use this code to get a TypeInitializationException with a NullRefernceException as an InnerException in Synchronize in SessionManager.GetInstance().GetAllActiveSessions() :
static void Main(string[] args) { try { var sessionManagerInstance = SessionManager.GetInstance(); } catch (TypeInitializationException e) { Console.WriteLine(e); throw; } }
Console output:
SessionManager constructor called RecoverState called SessionManagerDatabase constructor called Synchronize called System.TypeInitializationException: Der Typeninitialisierer für "SessionManager" hat eine Ausnahme verursacht. ---> System.TypeInitializationException: Der Typeninitialisierer für "SessionManagerDatabase" hat eine Ausnahme verursacht. ---> System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt. bei ConsoleApplication_CSharp.Program.SessionManagerDatabase.Synchronize() in ...... bei ConsoleApplication_CSharp.Program.SessionManagerDatabase..ctor() in ...... bei ConsoleApplication_CSharp.Program.SessionManagerDatabase..cctor() in ...... --- Ende der internen Ausnahmestapelüberwachung --- bei ConsoleApplication_CSharp.Program.SessionManagerDatabase.GetInstance() bei ConsoleApplication_CSharp.Program.SessionManager.RecoverState() in ...... bei ConsoleApplication_CSharp.Program.SessionManager..ctor() in ..... bei ConsoleApplication_CSharp.Program.SessionManager..cctor() in ...... --- Ende der internen Ausnahmestapelüberwachung --- bei ConsoleApplication_CSharp.Program.SessionManager.GetInstance() bei ConsoleApplication_CSharp.Program.Main(String[] args) in ......
I understand that there is some kind of cyclical dependency (it is not so obvious in the source code), but I still do not understand why the code does not initialize singletones. What would be the best approach for this use case other than avoiding circular dependencies?
source share