Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is implementing a singleton using an auto-property a good idea?

I recently found out about auto-properties and like them quite a lot. At this moment I am trying to use them everywhere where I can. Not really to just be able to use them everywhere, but more to see how well they work in most situations.

Now I am making a singleton and thought:"Hey, let's try auto-properties here as well".

public class MySingleton
{
    public static MySingleton MySingleton { get; private set; }

    private MySingleton() {}

    static MySingleton() { MySingleton = new MySingleton(); }
}

So my question is: "Is it a good idea to implement a singleton like this?"

I am not asking whether a singleton in general is a good idea.

like image 811
Matthijs Wessels Avatar asked Jan 22 '10 12:01

Matthijs Wessels


2 Answers

I wouldn't personally do that. I don't like using automatically implemented properties with a private setter that you never call where really you want a read-only property backed by a read-only variable. It's only one more line of code to be more explicit about what you mean:

public sealed class MySingleton
{
    private static readonly MySingleton mySingleton;
    public static MySingleton MySingleton { get { return mySingleton; } }

    private MySingleton() {}

    static MySingleton() { mySingleton = new MySingleton(); }
}

This way no-one's even tempted to change the singleton class to reassign either the property or the variable, because the compiler will stop them. They'd have to add a setter and/or make the variable non-readonly, which is a bigger change - one which hopefully they'd reconsider.

In other words:

  • Yes, it will work.
  • No, I don't think it's a good idea.

As of C# 6, this is easier with read-only automatically implemented properties though:

public sealed class MySingleton
{
    public static MySingleton MySingleton { get; } = new MySingleton();    
    private MySingleton() {}         
    static MySingleton() {}
}
like image 56
Jon Skeet Avatar answered Nov 05 '22 09:11

Jon Skeet


I would approach this from a slightly different direction than Jon. Regardless of whether the object is a singleton, is it logically best modeled as a property in the first place?

Properties are supposed to represent... properties. (Captain Obvious strikes again!) You know. Color. Length. Height. Name. Parent. All stuff that you would logically consider to be a property of a thing.

I cannot conceive of a property of an object which is logically a singleton. Maybe you've come up with a scenario that I haven't thought of; I haven't had any Diet Dr. Pepper yet this morning. But I am suspicious that this is an abuse of the model semantics.

Can you describe what the singleton is, and why you believe it to be a property of something?

All that said, I myself use this pattern frequently; usually like this:

class ImmutableStack<T>
{
    private static readonly ImmutableStack<T> emptystack = whatever;
    public static ImmutableStack<T> Empty { get { return emptystack; } }
    ...

Is "Empty" logically a property of an immutable stack? No. Here the compelling benefit of being able to say

var stack = ImmutableStack<int>.Empty;

trumps my desire for properties to logically be properties. Saying

var stack = ImmutableStack<int>.GetEmpty();

just seems weird.

Whether it is better in this case to have a readonly field and a regular property, or a static ctor and an autoprop, seems like less of an interesting question than whether to make it a property in the first place. In a "purist" mood I would likely side with Jon and make it a readonly field. But I also frequently use the pattern of making autoprops with private setters for logically immutable objects, just out of laziness.

How's that for taking all sides of a question?

like image 37
Eric Lippert Avatar answered Nov 05 '22 09:11

Eric Lippert