We have several slightly different classes.

class A{} class B{} 

we have Generic , which is a collection of objects of the above classes

 class Gen<T>{} 

The Gen<A> and Gen<B> collections must exist in a single copy. If I understood the documentation correctly, it’s impossible to make a singleton from a generic. To control the creation of collections, we use something like a factory method:

 class CollectionManager{ private static readonly CollectionManager _manager = new CollectionManager(); private CollectionManager(){}; public static CM {get {return _manager; }} private static Gen<A> _genA = new Gen<A>(); private static Gen<B> _genB = new Gen<B>(); public Gen<A> GenA { get { return _genA; }} ......... } 

And now the question: how to prohibit the explicit creation of Gen<A> from the program code? Those. to make the Gen<A> instance can only be obtained from the CollectionManager , and new Gen<A>() in the rest of the code is prohibited.

  • do the private designer. And where did you read that a singleton from a generic cannot be made ? - Grundy
  • 3
    Singleton from a generic can be done, like from any other class. - PashaPash
  • and an example is possible? I will not think - Ivan Nazarov
  • You have two singles right in the question. And even a singleton with the definition right in Gen<T> can be done completely - PashaPash
  • by and large, singleton is a class with a private constructor and one public property, such as an instance, which is filled once - Grundy

1 answer 1

Here is an example of a simple implementation.

 class A { } class B { } public class Gen<T> where T : class { private static Gen<T> _instance; protected Gen() { } public static Gen<T> Instance { get { return _instance ?? (_instance = new Gen<T>()); } } } 

We make a protected constructor, a private static variable for storing our single instance and the property (method) of access to it.

Here is an example call

 class Program { static void Main(string[] args) { // Успешное создание путём к обращению свойства синглтона var trueGenCreation = Gen<A>.Instance; // Попытка обращения к защищённому конструкторц var wrongGenCreation = new Gen<A>(); } } 

PS As noted in the comments, this implementation is not thread-safe and you can use the variant with a static constructor or using the Lazy class .

  • This is not a thread safe implementation. It is worth taking an implementation like ru.stackoverflow.com/a/486507/177221 - of the form of public static readonly Foo INSTANCE = new Foo(); . she is also lazy, but without problems with the flow. - PashaPash
  • Or, instead of a problem bike, apply Lazy<T> explicitly: csharpindepth.com/Articles/General/Singleton.aspx#lazy - VladD
  • @PashaPash can you explain how laziness is achieved in the implementation you specified? thread safety, as I understand it, will be guaranteed by a static constructor. - beta-tank
  • 2
    @ beta-tank: Laziness at the expense of the same. In C #, static constructors do not run vigorously, but when they first access the type. - VladD
  • one
    And by the way, the implementation of Wikipedia with reflection is terrible. - VladD