I ask this question out of curiosity.
Lets say the class Foo is a singleton and I want to call Foo instead of Foo.Instance to access the static object.
Would it be possible to encapsulate the object itself within a dynamic property?
Would C# allow me to create a dynamic property that refers to anything but a property of the said object?
Like so:
private static Foo _instance;
public static Foo this {
get {
if (_instance == null) {
_instance = new Foo();
}
return _instance;
}
}
public void Bar(){}
this would allow me to call
Foo.Bar();
instead of
Foo.Instance.Bar();
If this is possible, then in witch situation would it be viable to encapsulate any kind of object like this whithout using heritage
for example instead of:
class Ploof : List{}
we would have:
class Ploof {
private List _list;
public List this { get { return _list; } }
}
7
What you seem to want is a straight-up static class. The class and all its members are simply declared static. For instance:
public static class Foo
{
static Foo()
{
//initialize any state data needed by methods
}
public static void Bar()
{
//...
}
}
//usage, just as you wanted
Foo.Bar();
The basic problem with this is that everything in the class has to be declared static, and must always be accessed statically. That in turn means that once this code’s used in more than a couple of places, you really can’t ever change its architecture to be more object-oriented. It also usually means that the class can’t have any inheritance hierarchy, because any parent or child would also have to be static, and if the parent’s static and all children are static, you really just have three partial classes. In C# for instance, you can’t derive a static from any other class, and can’t inherit from a static; they’re single, isolated, widely-scoped oddities of your codebase.
Statics in general are to be minimized because, as above, they violate some key principles of SOLID code design, and of object-oriented code in general (in the real world which OOA&D attempts to model, there are very, very few object generalizations that have no parents, no children, and there are and can only ever be one of them).
These are the problems that the Singleton pattern solves, for the most part. The class itself is not static, but it has two or three static members; a constructor so it can self-initialize, and an instance accessor (which may use a specific backing field, or it may be an auto-property). While you still have static state and static availability which are kind of no-nos, the singleton allows you to use its instance as an instance, passing it around between classes and methods as a dependency, with none of those lower-level objects having to know it’s statically scoped or that there can only ever be one instance. Because the class itself isn’t static, if you wanted to, you could implement interfaces or even extend base classes, and you can theoretically derive from it, although that gets very tricky very quickly.
The tradeoff is always referencing the instance when using the singleton in static state. There are cute ways to mitigate it, but I only included the examples below because I thought they were funny; DO NOT USE THESE EVER:
public class F
{
static F() {instance = new F();}
private F() {...}
public static F oo {get{return instance;}}
public void Bar() {...}
}
...
//FXCop (and most of your fellow coders) will curse your name
F.oo.Bar();
public class Fo
{
static Fo() {instance = new Fo();}
private Fo() {...}
public static F this(int useZeroItsFunny) {get{return instance;}}
public void Bar() {...}
}
//a WTF if there ever was one...
Fo[0].Bar();
1
No, it isn’t.
But if you use the singleton often, you can always create local variable with reference to the instance.
But I would consider such heavy use of singleton as code smell and I would question if you really should be using a singleton.
No, there is (as far as I know) currently a limitation in the DLR where the dynamic overrides are not applied to static members. You can do tricks with a variable so that it redirects all calls to a singletone, or even via extension methods so that every object has a .Foo()
member you can call a singleton .Bar()
on. You can even do tricks with implicit conversion operators so that Ploof
looks and acts like a list.
But again, this is all horrible and ill advised – even more than singletons in the first place.