C# and Singletons

Started by
4 comments, last by EJH 13 years, 4 months ago
Hey folks,

I'm building a few bits and pieces in C# (xna) at the moment, and coming from a c++ background and having a few issues with the lack of multiple inheritance combined with a lack of macros.

I need a number of singleton instances for the game managers etc, and would like to use a base generic class to do this:

class Singleton<T> where T : new(){ public T GetInstance {  get  {    lock(padlock)    {      if( m_instance == null )      {        m_instance = new T();      }       return m_instance;    }  } } private static T m_instance; private static readonly object padlock = new object()}


So then I can create my singleton instances like this:

 class MyClass : Singleton<MyClass> {  ... }


Of course that means that I'm prevented from inheriting from any other classes. I guess I could get around it by having my singleton instances only inherit from the singleton class, but if anyone can think of a fancy way of getting around it I'm all ears :)
Advertisement
Quote:Original post by Capoeirista
Of course that means that I'm prevented from inheriting from any other classes. I guess I could get around it by having my singleton instances only inherit from the singleton class, but if anyone can think of a fancy way of getting around it I'm all ears :)

The solution is to not use singletons. The reasons why have been covered in the forums more times than you can count, but the short answer is that they're a poor design decision because they provide global access to things that don't necessarily need it and they arbitrarily restrict the ability to create additional objects if you decide it's necessary later on down the road.
Mike Popoloski | Journal | SlimDX
I would just make it a static class, then you don't have to muck around with stuff like a GetInstance method. Especially if you don't need more complex logic to control construction of the instance than what you have there (if null create instance else return instance). You can declare a static constructor that will initialize the class the first time it's accessed by other code.
Mike is wise. Singletons are one of those design patterns that people like to pick on and for good reason.

I'm personally not a fan of them, but in my own code I do use static classes in lieu of singletons. E.g. Math utility functions, debugging utility functions, etc. That still leaves the problem of needing to query some sort of service the managers provide, without having to pass references all over the place. I'm rather partial to the idea of "services".

For example, how XNA does game services. You have an IServiceProvider (GameServiceContainer) that's referenced by XNA Game. You either pass the provider reference to classes or have it as a static class. Then your managers are interfaces. That way you can query for a specific manager interface without having it coupled to a concrete implementation, and you could down the road create new managers and have them all in one place.

I use this setup in my own project at the moment that supports SlimDX (D3D10) and XNA, where at runtime the concrete implementations for vertex buffers, textures, shaders, etc are queried and my app code is independent of whatever rendering API I use.

Since you're using XNA you're in the perfect position of just using the game services functionality. And the good thing about using interfaces is you won't have your issue of not being able to inherit from another class.
Thanks for the advice folks, I spent a couple of hours last night getting rid of all of my singleton class instances (did a fair bit of trawling through the forums, reading all the flame wars) - it's surprising how quickly references to them spread through your code.

Much happier with my implementation now. I was using them for resource managers etc, but I'll go with your suggestion Starnick, and use the GameServiceContainer to keep track of instances.

Cheers!
Quote:Original post by Capoeirista
lack of multiple inheritance combined with a lack of macros


I think many would consider that a "feature" if other people are going to be reading your code. =)

As mentioned above, if you want a globally accessible class from anywhere in your code in C# just make the class "public static". No need for fiddling with the extra singleton code.

This topic is closed to new replies.

Advertisement