Home > Back-end >  this singleton has way can be improved?
this singleton has way can be improved?

Time:12-18

i was using google's singleton but this must need too many reference.

example, when I have to use another class in my Player class that used singleton, I must be using reference three time. Like this : Player.instance.another.blank=0;

my singleton

public static Player instance;

public void Awake()

{

if(instance ==null){

instance=this;

}

else

{

if(instance!=this){

Destroy(this.gameObject);

}

}

CodePudding user response:

Is there any reason to destroy the instance? Even so, we are not updating the existing instance immediately after destroying it whenever a player is added.

CodePudding user response:

I have a singleton Gist that I usually use: https://gist.github.com/xepherys/34d3d5ce3f44749e8649a25b38127347

It has decent comments for anyone unfamiliar with singletons, and is threadsafe. You can remove everything except the lazy field and the constructor region. I use this as the basis for Manager classes.

using System;

// Update namespace as needed
namespace WhatsYourName
{
    /*
    This is the name of your threadsafe Singleton - change "SingletonLazyThreadsafe" to value that makes sense, and be sure to use your
    editors [Rename] option, or update all values to match.

    Just because the Singleton itself is threadsafe does not mean that all methods that might be contained are automatically threadsafe.
    If threading is important, use threadsafe variables, such as:
    
        System.Collections.Concurrent.ConcurrentDictionary<TKey,TValue>
        https://docs.microsoft.com/en-us/dotnet/api/system.collections.concurrent.concurrentdictionary-2

    rather than:

        System.Collections.Generic.Dictionary<TKey,TValue>
        https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2

    Alternatively, lock() can be used in a pinch, but there is the potential for slight performance hits.
    
    Any field, property, or method not marked with "// REQUIRED" means that it's just a sample and can be removed or changed as needed.
    Comments are inline as a reminder and as a point of education for those not familiar with Singletons.

    Initial snippet added 12/08/2018 - JSW (Xepherys).
    */

    public class SingletonLazyThreadsafe
    {
        #region Fields
        // Private
        private static readonly Lazy<SingletonLazyThreadsafe> lazy = new Lazy<SingletonLazyThreadsafe>(() => new SingletonLazyThreadsafe());  // REQUIRED

        private int changeCount;
        private int myInteger;
        private string myString;

        // Public
        public char MyPublicChar;  // Note: Even though it's a field, if it's publicly accessible, I generally capitalize the first letter.  This is a personal design choice.  Most folk tend to use lowercase for fields regardless of their accessibility level.
        #endregion

        #region Properties
        // Note: Private getter/setter for private field.
        private int ChangeCount
        {
            get
            {
                return this.changeCount;
            }

            set
            {
                this.changeCount = value;
            }
        }

        // Note: Public getter/setter for private field.
        public int MyInteger
        {
            get
            {
                return this.myInteger;
            }

            set
            {
                this.myInteger = value;
            }
        }

        // Note: Public getter / protected setter for private field.  This allows a {get} from anywhere, but only a {set} from inside the class or derived classes.
        public string MyString
        {
            get
            {
                return this.myString;
            }

            protected set
            {
                this.myString = value;
            }
        }
        #endregion

        #region Constructors
        private SingletonLazyThreadsafe()  // REQUIRED
        { }

        public static SingletonLazyThreadsafe Instance  // REQUIRED
        {
            get
            {
                return lazy.Value;
            }
        }
        #endregion

        #region Methods
        // Note: This is a public method that just changes the myInteger field.  It's useless since the property is public, but it's just an example.  It also call IncreaseCount().
        public void IncrementInteger(int value)
        {
            this.MyInteger = value;
            IncreaseCount();
        }

        // Note: This is a public method that just changes the myString field.  It's useless since the property is public, but it's just an example.  It also call IncreaseCount().
        public void ChangeString(string value)
        {
            this.MyString = value;
            IncreaseCount();
        }

        // Note: This is a private method, which means it can only be called by other methods in this class, and not publicly or outside of the class.  While it could directly change
        //       'changeCount', I also have it making changes via the private 'ChangeCount' property, which is also only accessible inside the class.
        private void IncreaseCount()
        {
            this.ChangeCount  ;
        }
        #endregion
    }
}
  • Related