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