Les défauts d'implémentation du pattern singleton

The paradigm

Consider this common singleton pattern implementation:

The problem is that you can inherit this class and create a public constructor if there is no private constructor. Furthermore, static members are allowed. This is no longer a singleton at all. Setting the class as sealed can be an acceptable solution, but you must implement singleton by singleton, i.e., more than ten lines. Thus, coding a such singleton can be the source of many errors and difficulties. Thinking with factoring is not only an agile principle, it is a mathematical theorem.

Defining a generic singleton

A generic solution is to check the absence of static members and that there is only one parameterless private constructor, or an exception is thrown. Singletons that inherit this class can't be inherited and must be sealed. Moreover, the implementation of singleton types are checked at program startup. Therefore, it is not the best solution, but the only thing to do is to create one parameterless private constructor, no static members, and seal the class.

  Generic Persistent Singleton Sample

Taille : 53,4 Kio
Mise en ligne : 28 juillet 2009
Mise à jour : 8 septembre 2015
Dernier téléchargement : 31 juillet 2022
Nombre de téléchargements : 399

Here are members of the proposed singleton:

This is the declaration of a generic abstract class where T is a singleton.

By writing this, the type consistency is clear.

It is used to provide storage on disk for persistent singletons and to save their states.

This is the classic access to the instance of the singleton.

It creates a persistent instance : it deserialize the object from the disk or create a new. It uses a specific filename or a system name.

Note: defining the name after using the singleton doesn't load a new instance and should throw an error if the localization exists.

This creates the instance by invoking the default private constructor.

The singleton implementation validity is checked like indicated above.

Here are serialize and deserialize functions:

Coding the singleton

Startup checking

Here is the GetClasses function:

Example of usage

Each execution adds 10 to the value displayed by this program:

The missing "singleton" language keyword

The best way to implement a singleton in C# is to create a static class, but this may cause a problem with serialization and with when the object is initialized, whether one considers laziness.

The ideal thing would be to have a language keyword like singleton: an artifact having no static members and only one constructor with no parameter and no access modifier. It can be inherited only if marked as abstract. It may be used like a static class but will act like an instancied class. It may be serializable and disposable: the first usage deserializes the object if a stream is associated or creates a new single instance, disposing serializes the singleton or does nothing if no stream is associated, changing the stream moves the instance from the old to the new place, and setting a stream on a singleton already instancied causes a usage exception if the new stream localizes an item that exists.

Recommended articles

Implementing the Singleton Pattern in C#

Fun with Singletons in C# 2.0

Generic Singleton Pattern using Reflection in C#

Lazy Vs Eager Init Singletons / Double-Check Lock Pattern

The quest for the Generic singleton in C#