Un générique singleton
Ce gars, vous ne pensez à ce sujet pendant un générique singleton?
using System;
using System.Reflection;
//Use like this
/*
public class Highlander : Singleton<Highlander>
{
private Highlander()
{
Console.WriteLine("There can be only one...");
}
}
*/
public class Singleton<T> where T : class
{
private static T instance;
private static object initLock = new object();
public static T GetInstance()
{
if (instance == null)
{
CreateInstance();
}
return instance;
}
private static void CreateInstance()
{
lock (initLock)
{
if (instance == null)
{
Type t = typeof(T);
//Ensure there are no public constructors...
ConstructorInfo[] ctors = t.GetConstructors();
if (ctors.Length > 0)
{
throw new InvalidOperationException(String.Format("{0} has at least one accesible ctor making it impossible to enforce singleton behaviour", t.Name));
}
//Create an instance via the private constructor
instance = (T)Activator.CreateInstance(t, true);
}
}
}
}
- +1 pour le nom Highlander 😉
- Ce verrouillage technique est brisée, si un mot clé volatile est utilisé pour le verrouillage de l'objet. Voir ceci
- D'amende question pour codereview.stackexchange.com
Vous devez vous connecter pour publier un commentaire.
La création d'une classe singleton est juste quelques lignes de code, et avec la difficulté de faire un générique singleton j'ai toujours écrire ces lignes de code.
La
ligne élimine le besoin pour le verrouillage, comme un constructeur statique est thread-safe.
Bien, il n'est pas vraiment singleton - puisque vous ne pouvez pas contrôler
T
, il peut y avoir beaucoup deT
instances que vous le souhaitez.(supprimé thread-course; il a noté le double contrôle de l'utilisation)
J'ai supprimé ma réponse précédente que je n'avais pas remarqué le code qui vérifie la non-public des constructeurs. Cependant, c'est un contrôle qui est effectué uniquement au moment de l'exécution - il n'y a pas au moment de la compilation vérifier, qui est une grève contre elle. Il s'appuie également sur d'avoir suffisamment accès à l'appeler le non-public constructeur, qui ajoute certaines limites.
En outre, il n'interdit pas la interne constructeurs - de sorte que vous pouvez vous retrouver avec des non-singletons.
Je serais personnellement de créer une instance dans un constructeur statique pour un simple fil de sécurité, trop.
Fondamentalement, je ne suis pas vraiment un fan - c'est assez facile de créer des classes singleton, et vous ne devriez pas faire, ce qui, souvent, de toute façon. Les Singletons sont une douleur pour les tests, le découplage etc.
C'est mon point de vue à l'aide .NET 4
et il utilise est la suivante:
Fusion AndreasN réponse et Jon Skeet du "Quatrième version - pas tout à fait comme des paresseux, mais thread-safe, sans l'aide de verrous" d'un Singleton c# de mise en œuvre, pourquoi ne pas utiliser un extrait de code pour faire tout le travail difficile:
Ensuite, vous pouvez enregistrer ce dans un .snippt fichier et l'ajouter à VS IDE (Outils->Extraits de Code Manager)
Il y a un problème avec un générique de singleton, factory, car il est générique, vous n'avez pas de contrôle sur les
singleton
type qui est instancié, de sorte que vous pouvez jamais garantie que l'instance que vous créez sera la seule instance de l'application.Donc, vous ne pouvez pas créer un générique de singleton, factory - il sape le modèle lui-même.
Je ne pense pas que l'utilisation de génériques est utile pour les singletons. Parce que vous pouvez toujours créer plusieurs instances et à cet effet, il est pas, par définition, un singleton. Si vous avez besoin d'un paresseux singleton et de demander à un vrai singleton une solution simple (basé sur Alexandr exemple)
Vous ne pouvez pas refactoriser cette correctement dans un générique de singleton.
Voir aussi: http://csharpindepth.com/Articles/General/Singleton.aspx