Singleton Design Pattern implementation in a not traditional wayResourceManager SingletonCorrect way to...

Round towards zero

Handling Disruptive Student on the Autistic Spectrum

Is gzip atomic?

Prove your innocence

Is there any example of one country devastating a third?

Is a player able to change alignment midway through an adventure?

A discontinuity in an integral

How do I request a longer than normal leave of absence period for my wedding?

Justifying the use of directed energy weapons

Why did MS-DOS applications built using Turbo Pascal fail to start with a division by zero error on faster systems?

Is there any way to keep a player from killing an NPC?

What is a CirKle Word™?

Architectural feasibility of a tiered circular stone keep

How do you harvest carrots in creative mode?

Is there any music source code for sound chips?

I don't have the theoretical background in my PhD topic. I can't justify getting the degree

Who was president of the USA?

SQL Server Management Studio - Why is Dark Theme Disabled by Default?

Nothing like a good ol' game of ModTen

LeetCode: Group Anagrams C#

Numbers Decrease while Letters Increase

How many US airports have 4 or more parallel runways?

Strange-looking FM transmitter circuit

Non-visual Computers - thoughts?



Singleton Design Pattern implementation in a not traditional way


ResourceManager SingletonCorrect way to implement a Singleton fieldBuilding in the built-in declarationsSingleton Class for WordPress PluginThrowing exception in the singleton pattern in C#Singleton manager/service classes with mockable dependencies in swiftSimple builder pattern implementation for building immutable objectsSingleton Pattern + unavoidable Public Constructor






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}







16












$begingroup$


For implementing Singleton we can use Traditional way like this Article,
but i think that to write it in another way:



 public class Person
{
private static Person personInstance;
static Person()
{
personInstance = new Person();
}
private Person() { }

public static Person GetPersonInstance()
{
return personInstance;
}
}


As we know a Static Constructor will call automatically before the first instance is created or any static members are referenced and just once only. so if i write singleton like above, is it true (i mean this class is singleton)? or not?










share|improve this question









New contributor



pejman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$










  • 3




    $begingroup$
    csharpindepth.com/articles/singleton. Jon Skeet article on singleton. It's some kind of cannonical read before starting any conversation about singleton.
    $endgroup$
    – xdtTransform
    23 hours ago












  • $begingroup$
    I can't deal with the capitalization of SingleTonSample in the article OP posted.
    $endgroup$
    – JPhi1618
    15 hours ago


















16












$begingroup$


For implementing Singleton we can use Traditional way like this Article,
but i think that to write it in another way:



 public class Person
{
private static Person personInstance;
static Person()
{
personInstance = new Person();
}
private Person() { }

public static Person GetPersonInstance()
{
return personInstance;
}
}


As we know a Static Constructor will call automatically before the first instance is created or any static members are referenced and just once only. so if i write singleton like above, is it true (i mean this class is singleton)? or not?










share|improve this question









New contributor



pejman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$










  • 3




    $begingroup$
    csharpindepth.com/articles/singleton. Jon Skeet article on singleton. It's some kind of cannonical read before starting any conversation about singleton.
    $endgroup$
    – xdtTransform
    23 hours ago












  • $begingroup$
    I can't deal with the capitalization of SingleTonSample in the article OP posted.
    $endgroup$
    – JPhi1618
    15 hours ago














16












16








16


3



$begingroup$


For implementing Singleton we can use Traditional way like this Article,
but i think that to write it in another way:



 public class Person
{
private static Person personInstance;
static Person()
{
personInstance = new Person();
}
private Person() { }

public static Person GetPersonInstance()
{
return personInstance;
}
}


As we know a Static Constructor will call automatically before the first instance is created or any static members are referenced and just once only. so if i write singleton like above, is it true (i mean this class is singleton)? or not?










share|improve this question









New contributor



pejman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$




For implementing Singleton we can use Traditional way like this Article,
but i think that to write it in another way:



 public class Person
{
private static Person personInstance;
static Person()
{
personInstance = new Person();
}
private Person() { }

public static Person GetPersonInstance()
{
return personInstance;
}
}


As we know a Static Constructor will call automatically before the first instance is created or any static members are referenced and just once only. so if i write singleton like above, is it true (i mean this class is singleton)? or not?







c# design-patterns singleton






share|improve this question









New contributor



pejman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.










share|improve this question









New contributor



pejman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








share|improve this question




share|improve this question








edited 2 days ago







pejman













New contributor



pejman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








asked 2 days ago









pejmanpejman

1835 bronze badges




1835 bronze badges




New contributor



pejman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




New contributor




pejman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.













  • 3




    $begingroup$
    csharpindepth.com/articles/singleton. Jon Skeet article on singleton. It's some kind of cannonical read before starting any conversation about singleton.
    $endgroup$
    – xdtTransform
    23 hours ago












  • $begingroup$
    I can't deal with the capitalization of SingleTonSample in the article OP posted.
    $endgroup$
    – JPhi1618
    15 hours ago














  • 3




    $begingroup$
    csharpindepth.com/articles/singleton. Jon Skeet article on singleton. It's some kind of cannonical read before starting any conversation about singleton.
    $endgroup$
    – xdtTransform
    23 hours ago












  • $begingroup$
    I can't deal with the capitalization of SingleTonSample in the article OP posted.
    $endgroup$
    – JPhi1618
    15 hours ago








3




3




$begingroup$
csharpindepth.com/articles/singleton. Jon Skeet article on singleton. It's some kind of cannonical read before starting any conversation about singleton.
$endgroup$
– xdtTransform
23 hours ago






$begingroup$
csharpindepth.com/articles/singleton. Jon Skeet article on singleton. It's some kind of cannonical read before starting any conversation about singleton.
$endgroup$
– xdtTransform
23 hours ago














$begingroup$
I can't deal with the capitalization of SingleTonSample in the article OP posted.
$endgroup$
– JPhi1618
15 hours ago




$begingroup$
I can't deal with the capitalization of SingleTonSample in the article OP posted.
$endgroup$
– JPhi1618
15 hours ago










2 Answers
2






active

oldest

votes


















19













$begingroup$

Your implementation does the trick. For what it's worth, I would consider your implementation the current "traditional way". It is thread-safe. The static constructor is guaranteed to run only once, so you won't accidentally end up with two instances if two threads try to grab the instance for the first time simultaneously.



Laziness



There is one more thing you might want to consider though. Because of the way the static constructor works, it is executed the first time the class is referenced in the code. This means that the instance in your singleton is created, even when you don't try to grab the instance, but another static variable perhaps.



To fix this, you might want to make the creation of the instance lazy, so that it really only fires when you need it. To do this, you can use the Lazy<T> class.



Sealed



This is mostly a formality, but it's nice when trying to do it formally. The sealed keyword means that that class cannot be inherited from. The private constructor already ensured that, but this makes it more explicit.



Readonly



As Jesse mentioned in the comments, it's a good idea to make the instance field (lazy or not) readonly. This prevents you from accidentally mucking up your singleton instance from within the class.



public sealed class Person
{
private Person() { }
private static readonly Lazy<Person> lazyPersonInstance = new Lazy<Person>(() => new Person());
public static Person GetPersonInstance()
{
return lazyPersonInstance.Value;
}
}


Your method GetPersonInstance can also be a getter-property:



    public static Person Instance => lazyPersonInstance.Value;


Exceptions



IEatBagels already posted an answer about throwing exceptions. I'll elaborate a bit on how it would work in this example. We're looking at the scenario where instantiating the singleton instance throws an exception.



In your code, this exception would be thrown when the static constructor is ran. As IEatBagels points out, when this happens, the type is broken for the rest of the "program". This means that you have one shot at creating your instance.



In my example, the initiation of the instance does not happen during the execution of the static constructor. All we do during static initialization - static constructor and static fields act similarly IIRC - is creating the Lazy<T> object with the factory method. This method is only executed when lazyPersonInstance.Value is called.



However, Lazy<T> caches exceptions. This means that if the factory method throws an exception, that exception will be rethrown on every subsequent call to lazyPersonInstance.Value. Without re-executing the factory method. So in the end, this is the same problem as the static constructor problem. The Lazy<T> docs have the following to say:




The Lazy stands in for an actual T that otherwise would have been initialized at some earlier point, usually during startup. A failure at that earlier point is usually fatal. If there is a potential for a recoverable failure, we recommend that you build the retry logic into the initialization routine (in this case, the factory method), just as you would if you weren't using lazy initialization.
MSDN docs




So if you really must throw exceptions in your constructor, be sure to handle them in the factory method.



Exceptions and thread-safety



There's one more workaround for the problem of exceptions in constructors. Lazy has three thread-safety modes, defined in the enum System.Threading.LazyThreadSafetyMode which can be passed to the constructor of Lazy<T>.





  1. None. No thread safety.


  2. ExecutionAndPublication. This is the default. This ensures that the factory method is executed only once, and that the object on lazy.Value is always the same across threads.


  3. PublicationOnly. This only ensures thread-safety on lazy.Value. It can happen that the factory method is executed simultaneously by multiple threads, but the resulting instance is still the same. The others are discarded. According to the Lazy<T> docs, Exceptions are not cached here.


This leaves you, the implementer of the singleton with a decision: if there are exceptions that might be thrown, that can't be handled within the factory method, and that might not throw in subsequent attempts (weird, but might happen), you could consider loosening up some of the locking on Lazy to allow for this behaviour.





For further reading, see this blog post by Jon Skeet.






share|improve this answer











$endgroup$











  • 4




    $begingroup$
    One small note - to truly be a singleton, the class should also be sealed so no inheritors can be created and change behavior.
    $endgroup$
    – Jesse C. Slicer
    yesterday






  • 4




    $begingroup$
    @jessecslicer hmm, I was going to mention that, but the private constructor already prevents inheritance. It's never a bad idea though.
    $endgroup$
    – JAD
    yesterday






  • 5




    $begingroup$
    I'd probably also mark lazyPersonInstance as readonly to keep other methods from being able to muck around with it, even by accident.
    $endgroup$
    – Jesse C. Slicer
    yesterday






  • 1




    $begingroup$
    @JesseC.Slicer thanks, added :)
    $endgroup$
    – JAD
    yesterday



















9













$begingroup$

There's a potential bug with this scenario.



According to this Jon Skeet post, if an exception is thrown inside the static constructor, it is never retried. Which means that if your Singleton initialization has a problem, your Singleton is doomed for the lifetime of your application, which normally isn't a problem with the "traditional" way of doing it.






share|improve this answer









$endgroup$















  • $begingroup$
    good catch. real world (constructors) vs academic examples.
    $endgroup$
    – granadaCoder
    16 hours ago














Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});






pejman is a new contributor. Be nice, and check out our Code of Conduct.










draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f226611%2fsingleton-design-pattern-implementation-in-a-not-traditional-way%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









19













$begingroup$

Your implementation does the trick. For what it's worth, I would consider your implementation the current "traditional way". It is thread-safe. The static constructor is guaranteed to run only once, so you won't accidentally end up with two instances if two threads try to grab the instance for the first time simultaneously.



Laziness



There is one more thing you might want to consider though. Because of the way the static constructor works, it is executed the first time the class is referenced in the code. This means that the instance in your singleton is created, even when you don't try to grab the instance, but another static variable perhaps.



To fix this, you might want to make the creation of the instance lazy, so that it really only fires when you need it. To do this, you can use the Lazy<T> class.



Sealed



This is mostly a formality, but it's nice when trying to do it formally. The sealed keyword means that that class cannot be inherited from. The private constructor already ensured that, but this makes it more explicit.



Readonly



As Jesse mentioned in the comments, it's a good idea to make the instance field (lazy or not) readonly. This prevents you from accidentally mucking up your singleton instance from within the class.



public sealed class Person
{
private Person() { }
private static readonly Lazy<Person> lazyPersonInstance = new Lazy<Person>(() => new Person());
public static Person GetPersonInstance()
{
return lazyPersonInstance.Value;
}
}


Your method GetPersonInstance can also be a getter-property:



    public static Person Instance => lazyPersonInstance.Value;


Exceptions



IEatBagels already posted an answer about throwing exceptions. I'll elaborate a bit on how it would work in this example. We're looking at the scenario where instantiating the singleton instance throws an exception.



In your code, this exception would be thrown when the static constructor is ran. As IEatBagels points out, when this happens, the type is broken for the rest of the "program". This means that you have one shot at creating your instance.



In my example, the initiation of the instance does not happen during the execution of the static constructor. All we do during static initialization - static constructor and static fields act similarly IIRC - is creating the Lazy<T> object with the factory method. This method is only executed when lazyPersonInstance.Value is called.



However, Lazy<T> caches exceptions. This means that if the factory method throws an exception, that exception will be rethrown on every subsequent call to lazyPersonInstance.Value. Without re-executing the factory method. So in the end, this is the same problem as the static constructor problem. The Lazy<T> docs have the following to say:




The Lazy stands in for an actual T that otherwise would have been initialized at some earlier point, usually during startup. A failure at that earlier point is usually fatal. If there is a potential for a recoverable failure, we recommend that you build the retry logic into the initialization routine (in this case, the factory method), just as you would if you weren't using lazy initialization.
MSDN docs




So if you really must throw exceptions in your constructor, be sure to handle them in the factory method.



Exceptions and thread-safety



There's one more workaround for the problem of exceptions in constructors. Lazy has three thread-safety modes, defined in the enum System.Threading.LazyThreadSafetyMode which can be passed to the constructor of Lazy<T>.





  1. None. No thread safety.


  2. ExecutionAndPublication. This is the default. This ensures that the factory method is executed only once, and that the object on lazy.Value is always the same across threads.


  3. PublicationOnly. This only ensures thread-safety on lazy.Value. It can happen that the factory method is executed simultaneously by multiple threads, but the resulting instance is still the same. The others are discarded. According to the Lazy<T> docs, Exceptions are not cached here.


This leaves you, the implementer of the singleton with a decision: if there are exceptions that might be thrown, that can't be handled within the factory method, and that might not throw in subsequent attempts (weird, but might happen), you could consider loosening up some of the locking on Lazy to allow for this behaviour.





For further reading, see this blog post by Jon Skeet.






share|improve this answer











$endgroup$











  • 4




    $begingroup$
    One small note - to truly be a singleton, the class should also be sealed so no inheritors can be created and change behavior.
    $endgroup$
    – Jesse C. Slicer
    yesterday






  • 4




    $begingroup$
    @jessecslicer hmm, I was going to mention that, but the private constructor already prevents inheritance. It's never a bad idea though.
    $endgroup$
    – JAD
    yesterday






  • 5




    $begingroup$
    I'd probably also mark lazyPersonInstance as readonly to keep other methods from being able to muck around with it, even by accident.
    $endgroup$
    – Jesse C. Slicer
    yesterday






  • 1




    $begingroup$
    @JesseC.Slicer thanks, added :)
    $endgroup$
    – JAD
    yesterday
















19













$begingroup$

Your implementation does the trick. For what it's worth, I would consider your implementation the current "traditional way". It is thread-safe. The static constructor is guaranteed to run only once, so you won't accidentally end up with two instances if two threads try to grab the instance for the first time simultaneously.



Laziness



There is one more thing you might want to consider though. Because of the way the static constructor works, it is executed the first time the class is referenced in the code. This means that the instance in your singleton is created, even when you don't try to grab the instance, but another static variable perhaps.



To fix this, you might want to make the creation of the instance lazy, so that it really only fires when you need it. To do this, you can use the Lazy<T> class.



Sealed



This is mostly a formality, but it's nice when trying to do it formally. The sealed keyword means that that class cannot be inherited from. The private constructor already ensured that, but this makes it more explicit.



Readonly



As Jesse mentioned in the comments, it's a good idea to make the instance field (lazy or not) readonly. This prevents you from accidentally mucking up your singleton instance from within the class.



public sealed class Person
{
private Person() { }
private static readonly Lazy<Person> lazyPersonInstance = new Lazy<Person>(() => new Person());
public static Person GetPersonInstance()
{
return lazyPersonInstance.Value;
}
}


Your method GetPersonInstance can also be a getter-property:



    public static Person Instance => lazyPersonInstance.Value;


Exceptions



IEatBagels already posted an answer about throwing exceptions. I'll elaborate a bit on how it would work in this example. We're looking at the scenario where instantiating the singleton instance throws an exception.



In your code, this exception would be thrown when the static constructor is ran. As IEatBagels points out, when this happens, the type is broken for the rest of the "program". This means that you have one shot at creating your instance.



In my example, the initiation of the instance does not happen during the execution of the static constructor. All we do during static initialization - static constructor and static fields act similarly IIRC - is creating the Lazy<T> object with the factory method. This method is only executed when lazyPersonInstance.Value is called.



However, Lazy<T> caches exceptions. This means that if the factory method throws an exception, that exception will be rethrown on every subsequent call to lazyPersonInstance.Value. Without re-executing the factory method. So in the end, this is the same problem as the static constructor problem. The Lazy<T> docs have the following to say:




The Lazy stands in for an actual T that otherwise would have been initialized at some earlier point, usually during startup. A failure at that earlier point is usually fatal. If there is a potential for a recoverable failure, we recommend that you build the retry logic into the initialization routine (in this case, the factory method), just as you would if you weren't using lazy initialization.
MSDN docs




So if you really must throw exceptions in your constructor, be sure to handle them in the factory method.



Exceptions and thread-safety



There's one more workaround for the problem of exceptions in constructors. Lazy has three thread-safety modes, defined in the enum System.Threading.LazyThreadSafetyMode which can be passed to the constructor of Lazy<T>.





  1. None. No thread safety.


  2. ExecutionAndPublication. This is the default. This ensures that the factory method is executed only once, and that the object on lazy.Value is always the same across threads.


  3. PublicationOnly. This only ensures thread-safety on lazy.Value. It can happen that the factory method is executed simultaneously by multiple threads, but the resulting instance is still the same. The others are discarded. According to the Lazy<T> docs, Exceptions are not cached here.


This leaves you, the implementer of the singleton with a decision: if there are exceptions that might be thrown, that can't be handled within the factory method, and that might not throw in subsequent attempts (weird, but might happen), you could consider loosening up some of the locking on Lazy to allow for this behaviour.





For further reading, see this blog post by Jon Skeet.






share|improve this answer











$endgroup$











  • 4




    $begingroup$
    One small note - to truly be a singleton, the class should also be sealed so no inheritors can be created and change behavior.
    $endgroup$
    – Jesse C. Slicer
    yesterday






  • 4




    $begingroup$
    @jessecslicer hmm, I was going to mention that, but the private constructor already prevents inheritance. It's never a bad idea though.
    $endgroup$
    – JAD
    yesterday






  • 5




    $begingroup$
    I'd probably also mark lazyPersonInstance as readonly to keep other methods from being able to muck around with it, even by accident.
    $endgroup$
    – Jesse C. Slicer
    yesterday






  • 1




    $begingroup$
    @JesseC.Slicer thanks, added :)
    $endgroup$
    – JAD
    yesterday














19














19










19







$begingroup$

Your implementation does the trick. For what it's worth, I would consider your implementation the current "traditional way". It is thread-safe. The static constructor is guaranteed to run only once, so you won't accidentally end up with two instances if two threads try to grab the instance for the first time simultaneously.



Laziness



There is one more thing you might want to consider though. Because of the way the static constructor works, it is executed the first time the class is referenced in the code. This means that the instance in your singleton is created, even when you don't try to grab the instance, but another static variable perhaps.



To fix this, you might want to make the creation of the instance lazy, so that it really only fires when you need it. To do this, you can use the Lazy<T> class.



Sealed



This is mostly a formality, but it's nice when trying to do it formally. The sealed keyword means that that class cannot be inherited from. The private constructor already ensured that, but this makes it more explicit.



Readonly



As Jesse mentioned in the comments, it's a good idea to make the instance field (lazy or not) readonly. This prevents you from accidentally mucking up your singleton instance from within the class.



public sealed class Person
{
private Person() { }
private static readonly Lazy<Person> lazyPersonInstance = new Lazy<Person>(() => new Person());
public static Person GetPersonInstance()
{
return lazyPersonInstance.Value;
}
}


Your method GetPersonInstance can also be a getter-property:



    public static Person Instance => lazyPersonInstance.Value;


Exceptions



IEatBagels already posted an answer about throwing exceptions. I'll elaborate a bit on how it would work in this example. We're looking at the scenario where instantiating the singleton instance throws an exception.



In your code, this exception would be thrown when the static constructor is ran. As IEatBagels points out, when this happens, the type is broken for the rest of the "program". This means that you have one shot at creating your instance.



In my example, the initiation of the instance does not happen during the execution of the static constructor. All we do during static initialization - static constructor and static fields act similarly IIRC - is creating the Lazy<T> object with the factory method. This method is only executed when lazyPersonInstance.Value is called.



However, Lazy<T> caches exceptions. This means that if the factory method throws an exception, that exception will be rethrown on every subsequent call to lazyPersonInstance.Value. Without re-executing the factory method. So in the end, this is the same problem as the static constructor problem. The Lazy<T> docs have the following to say:




The Lazy stands in for an actual T that otherwise would have been initialized at some earlier point, usually during startup. A failure at that earlier point is usually fatal. If there is a potential for a recoverable failure, we recommend that you build the retry logic into the initialization routine (in this case, the factory method), just as you would if you weren't using lazy initialization.
MSDN docs




So if you really must throw exceptions in your constructor, be sure to handle them in the factory method.



Exceptions and thread-safety



There's one more workaround for the problem of exceptions in constructors. Lazy has three thread-safety modes, defined in the enum System.Threading.LazyThreadSafetyMode which can be passed to the constructor of Lazy<T>.





  1. None. No thread safety.


  2. ExecutionAndPublication. This is the default. This ensures that the factory method is executed only once, and that the object on lazy.Value is always the same across threads.


  3. PublicationOnly. This only ensures thread-safety on lazy.Value. It can happen that the factory method is executed simultaneously by multiple threads, but the resulting instance is still the same. The others are discarded. According to the Lazy<T> docs, Exceptions are not cached here.


This leaves you, the implementer of the singleton with a decision: if there are exceptions that might be thrown, that can't be handled within the factory method, and that might not throw in subsequent attempts (weird, but might happen), you could consider loosening up some of the locking on Lazy to allow for this behaviour.





For further reading, see this blog post by Jon Skeet.






share|improve this answer











$endgroup$



Your implementation does the trick. For what it's worth, I would consider your implementation the current "traditional way". It is thread-safe. The static constructor is guaranteed to run only once, so you won't accidentally end up with two instances if two threads try to grab the instance for the first time simultaneously.



Laziness



There is one more thing you might want to consider though. Because of the way the static constructor works, it is executed the first time the class is referenced in the code. This means that the instance in your singleton is created, even when you don't try to grab the instance, but another static variable perhaps.



To fix this, you might want to make the creation of the instance lazy, so that it really only fires when you need it. To do this, you can use the Lazy<T> class.



Sealed



This is mostly a formality, but it's nice when trying to do it formally. The sealed keyword means that that class cannot be inherited from. The private constructor already ensured that, but this makes it more explicit.



Readonly



As Jesse mentioned in the comments, it's a good idea to make the instance field (lazy or not) readonly. This prevents you from accidentally mucking up your singleton instance from within the class.



public sealed class Person
{
private Person() { }
private static readonly Lazy<Person> lazyPersonInstance = new Lazy<Person>(() => new Person());
public static Person GetPersonInstance()
{
return lazyPersonInstance.Value;
}
}


Your method GetPersonInstance can also be a getter-property:



    public static Person Instance => lazyPersonInstance.Value;


Exceptions



IEatBagels already posted an answer about throwing exceptions. I'll elaborate a bit on how it would work in this example. We're looking at the scenario where instantiating the singleton instance throws an exception.



In your code, this exception would be thrown when the static constructor is ran. As IEatBagels points out, when this happens, the type is broken for the rest of the "program". This means that you have one shot at creating your instance.



In my example, the initiation of the instance does not happen during the execution of the static constructor. All we do during static initialization - static constructor and static fields act similarly IIRC - is creating the Lazy<T> object with the factory method. This method is only executed when lazyPersonInstance.Value is called.



However, Lazy<T> caches exceptions. This means that if the factory method throws an exception, that exception will be rethrown on every subsequent call to lazyPersonInstance.Value. Without re-executing the factory method. So in the end, this is the same problem as the static constructor problem. The Lazy<T> docs have the following to say:




The Lazy stands in for an actual T that otherwise would have been initialized at some earlier point, usually during startup. A failure at that earlier point is usually fatal. If there is a potential for a recoverable failure, we recommend that you build the retry logic into the initialization routine (in this case, the factory method), just as you would if you weren't using lazy initialization.
MSDN docs




So if you really must throw exceptions in your constructor, be sure to handle them in the factory method.



Exceptions and thread-safety



There's one more workaround for the problem of exceptions in constructors. Lazy has three thread-safety modes, defined in the enum System.Threading.LazyThreadSafetyMode which can be passed to the constructor of Lazy<T>.





  1. None. No thread safety.


  2. ExecutionAndPublication. This is the default. This ensures that the factory method is executed only once, and that the object on lazy.Value is always the same across threads.


  3. PublicationOnly. This only ensures thread-safety on lazy.Value. It can happen that the factory method is executed simultaneously by multiple threads, but the resulting instance is still the same. The others are discarded. According to the Lazy<T> docs, Exceptions are not cached here.


This leaves you, the implementer of the singleton with a decision: if there are exceptions that might be thrown, that can't be handled within the factory method, and that might not throw in subsequent attempts (weird, but might happen), you could consider loosening up some of the locking on Lazy to allow for this behaviour.





For further reading, see this blog post by Jon Skeet.







share|improve this answer














share|improve this answer



share|improve this answer








edited 23 hours ago

























answered yesterday









JADJAD

1,1251 gold badge6 silver badges23 bronze badges




1,1251 gold badge6 silver badges23 bronze badges











  • 4




    $begingroup$
    One small note - to truly be a singleton, the class should also be sealed so no inheritors can be created and change behavior.
    $endgroup$
    – Jesse C. Slicer
    yesterday






  • 4




    $begingroup$
    @jessecslicer hmm, I was going to mention that, but the private constructor already prevents inheritance. It's never a bad idea though.
    $endgroup$
    – JAD
    yesterday






  • 5




    $begingroup$
    I'd probably also mark lazyPersonInstance as readonly to keep other methods from being able to muck around with it, even by accident.
    $endgroup$
    – Jesse C. Slicer
    yesterday






  • 1




    $begingroup$
    @JesseC.Slicer thanks, added :)
    $endgroup$
    – JAD
    yesterday














  • 4




    $begingroup$
    One small note - to truly be a singleton, the class should also be sealed so no inheritors can be created and change behavior.
    $endgroup$
    – Jesse C. Slicer
    yesterday






  • 4




    $begingroup$
    @jessecslicer hmm, I was going to mention that, but the private constructor already prevents inheritance. It's never a bad idea though.
    $endgroup$
    – JAD
    yesterday






  • 5




    $begingroup$
    I'd probably also mark lazyPersonInstance as readonly to keep other methods from being able to muck around with it, even by accident.
    $endgroup$
    – Jesse C. Slicer
    yesterday






  • 1




    $begingroup$
    @JesseC.Slicer thanks, added :)
    $endgroup$
    – JAD
    yesterday








4




4




$begingroup$
One small note - to truly be a singleton, the class should also be sealed so no inheritors can be created and change behavior.
$endgroup$
– Jesse C. Slicer
yesterday




$begingroup$
One small note - to truly be a singleton, the class should also be sealed so no inheritors can be created and change behavior.
$endgroup$
– Jesse C. Slicer
yesterday




4




4




$begingroup$
@jessecslicer hmm, I was going to mention that, but the private constructor already prevents inheritance. It's never a bad idea though.
$endgroup$
– JAD
yesterday




$begingroup$
@jessecslicer hmm, I was going to mention that, but the private constructor already prevents inheritance. It's never a bad idea though.
$endgroup$
– JAD
yesterday




5




5




$begingroup$
I'd probably also mark lazyPersonInstance as readonly to keep other methods from being able to muck around with it, even by accident.
$endgroup$
– Jesse C. Slicer
yesterday




$begingroup$
I'd probably also mark lazyPersonInstance as readonly to keep other methods from being able to muck around with it, even by accident.
$endgroup$
– Jesse C. Slicer
yesterday




1




1




$begingroup$
@JesseC.Slicer thanks, added :)
$endgroup$
– JAD
yesterday




$begingroup$
@JesseC.Slicer thanks, added :)
$endgroup$
– JAD
yesterday













9













$begingroup$

There's a potential bug with this scenario.



According to this Jon Skeet post, if an exception is thrown inside the static constructor, it is never retried. Which means that if your Singleton initialization has a problem, your Singleton is doomed for the lifetime of your application, which normally isn't a problem with the "traditional" way of doing it.






share|improve this answer









$endgroup$















  • $begingroup$
    good catch. real world (constructors) vs academic examples.
    $endgroup$
    – granadaCoder
    16 hours ago
















9













$begingroup$

There's a potential bug with this scenario.



According to this Jon Skeet post, if an exception is thrown inside the static constructor, it is never retried. Which means that if your Singleton initialization has a problem, your Singleton is doomed for the lifetime of your application, which normally isn't a problem with the "traditional" way of doing it.






share|improve this answer









$endgroup$















  • $begingroup$
    good catch. real world (constructors) vs academic examples.
    $endgroup$
    – granadaCoder
    16 hours ago














9














9










9







$begingroup$

There's a potential bug with this scenario.



According to this Jon Skeet post, if an exception is thrown inside the static constructor, it is never retried. Which means that if your Singleton initialization has a problem, your Singleton is doomed for the lifetime of your application, which normally isn't a problem with the "traditional" way of doing it.






share|improve this answer









$endgroup$



There's a potential bug with this scenario.



According to this Jon Skeet post, if an exception is thrown inside the static constructor, it is never retried. Which means that if your Singleton initialization has a problem, your Singleton is doomed for the lifetime of your application, which normally isn't a problem with the "traditional" way of doing it.







share|improve this answer












share|improve this answer



share|improve this answer










answered yesterday









IEatBagelsIEatBagels

9,9502 gold badges35 silver badges86 bronze badges




9,9502 gold badges35 silver badges86 bronze badges















  • $begingroup$
    good catch. real world (constructors) vs academic examples.
    $endgroup$
    – granadaCoder
    16 hours ago


















  • $begingroup$
    good catch. real world (constructors) vs academic examples.
    $endgroup$
    – granadaCoder
    16 hours ago
















$begingroup$
good catch. real world (constructors) vs academic examples.
$endgroup$
– granadaCoder
16 hours ago




$begingroup$
good catch. real world (constructors) vs academic examples.
$endgroup$
– granadaCoder
16 hours ago










pejman is a new contributor. Be nice, and check out our Code of Conduct.










draft saved

draft discarded


















pejman is a new contributor. Be nice, and check out our Code of Conduct.













pejman is a new contributor. Be nice, and check out our Code of Conduct.












pejman is a new contributor. Be nice, and check out our Code of Conduct.
















Thanks for contributing an answer to Code Review Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


Use MathJax to format equations. MathJax reference.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f226611%2fsingleton-design-pattern-implementation-in-a-not-traditional-way%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Taj Mahal Inhaltsverzeichnis Aufbau | Geschichte | 350-Jahr-Feier | Heutige Bedeutung | Siehe auch |...

Baia Sprie Cuprins Etimologie | Istorie | Demografie | Politică și administrație | Arii naturale...

Nicolae Petrescu-Găină Cuprins Biografie | Opera | In memoriam | Varia | Controverse, incertitudini...