Thread safety for initializers and linked list assignments?

  • Thread starter Thread starter Siegfried Heintze
  • Start date Start date
S

Siegfried Heintze

I have a class that has no ancestors and only static data members of type
string and ListDictionary. I am not allowed to use a static constructor.



Here is the code:

class sql{

private static string LogSource=abc();



// Hold a list of databases and their configuration values
private static ListDictionary DBList = Init();
 
Siegfried Heintze said:
I have a class that has no ancestors and only static data members of type
string and ListDictionary. I am not allowed to use a static constructor.

Using a static constructor would just give more definite guarantees
about *exactly* when it would be called. The normal guarantee around
"called only once" applies, and that will happen at some point before
the first use of any static field in the type.

1. Is the initializer for LogSource (function abc) guaranteed to
execute before Init?
Yes.

2. Is the assignment part of the call to the initializer for DBList
thread safe?
Yes.

3. Presently, the implementation of function init does everything
inside a lock statement. Is this lock statement superfluous?

Assuming it doesn't touch anything else, yes.
 
Siegfried said:
I have a class that has no ancestors and only static data members of type
string and ListDictionary. I am not allowed to use a static constructor.
From who stems this grim edict? Someone with more authority than sense?
Here is the code:

class sql{

private static string LogSource=abc();



// Hold a list of databases and their configuration values
private static ListDictionary DBList = Init();
I hate to be a spoilsport, but this uses a static constructor under the
hood. Internally, this is simply transformed into

private static string LogSource;
private static ListDictionary DBList;

static sql() {
LogSource = abc();
DBList = Init();
}

This doesn't actually have the *exact* same semantics, for nerdy technical
reasons that are well explained here:
http://yoda.arachsys.com/csharp/beforefieldinit.html
Function Init also initializes LogSource. (Don't complain to me, I did not
write this code. I'm just refactoring it).



Questions:



1. Is the initializer for LogSource (function abc) guaranteed to
execute before Init?
Yes, by virtue of the language specification, but it's *extremely* unwise to
depend on this. Most people would assume that the order of fields doesn't
matter. For purposes of initialization, it does, but someone could come
along and reorder the fields for bizarre esthetic reasons and suddenly break
the code.

If you need to initialize fields in a particular order, writing out a static
constructor is a much better idea.
2. Is the assignment part of the call to the initializer for DBList
thread safe?
Yes. Static initialization is thread-safe. However, read the article I
mentioned above carefully. Under circumstances it's possible to have an
instance before the static field was initialized. While this has nothing to
do with thread-safety per se, it can lead to the same sort of surprise.
3. Presently, the implementation of function init does everything
inside a lock statement. Is this lock statement superfluous?
Yes. Static initialization is only performed once; this is guaranteed by the
runtime.

As an aside, if the fields will never have their value changed, it helps if
you make this clear to both the compiler and the readers by marking them
"readonly".
 
Back
Top