Your code includes a closed static initialized instance:
private static Foo instance = new Foo();
Do you assume that this means that the instance constructor will always work before accessing any static method, so providing bar initialization?
In the single-threaded case, I think you're right.
Sequence of events:
- Call
Foo.BarLength() - Static
Foo class initialization (if not completed yet) - Static initialization of private static member
instance with instance Foo - Entrance to
Foo.BarLength()
However, static class initialization is triggered only once in the application domain - and there is no lock to ensure its completion before any other static methods are called.
So you might have a scenario like this:
- Stream Alphabet: Call
Foo.BarLength() - Thread Alpha: Static Initialization of a
Foo Class (if Not Completed) Launches - Context switch
- Beta theme: calling
Foo.BarLength() - Topic beta: There is no static initialization call to the
Foo class, as it is already running - Beta theme: login to
Foo.BarLength() - Topic beta: accessing the
null static member instance
The Contract Analyzer does not know that you never run the code in a multithreaded way, therefore it should be mistaken on the part of caution.
Bevan
source share