I came across some singleton code today in our code base
Do you have such confusing code throughout your code base? This code does the same:
if (_s == null) _s = new S(); return _s;
and about a thousand times easier to read.
I think that??? just a trick compiler and that the resulting code is still not atomic
You're right. C # gives the following atomicity guarantees:
Read and write the following data types: atomic: bool, char, byte, sbyte, short, ushort, uint, int, float and reference. In addition, reading and writing enumeration types with a base type in the previous list are also atomic. Reads and writes of other types, including long, stole, double and decimal, as well as user-defined types, are not guaranteed to be atomic. In addition to library functions intended for this purpose, there is no guarantee of atomic read-modify-write, for example, in the case of increment or decrement.
The zero coalescence operator is not included in this list of guarantees.
To guarantee atomicity, we would have to block this bit of code:
lock (_sentence) { return _sentence ?? (_sentence = new Sentence()); } } }
Oh my god no This is a glitch immediately!
The most correct way to do this is:
- Stop trying to write multithreaded code.
- Write a singleton using one of the safe Jon Skeet singleton samples on your singles page.
- Use the
Lazy<T> class. - Locks an object intended to lock this variable.
- Use the Interlocked Compare Exchange to perform an atomic test and installation.
Eric Lippert
source share