Using Singleton in C#

2019-08-29 20:50发布

问题:

I'm trying to create an instance of a class to be used throughout the application.

I have two forms: form1 and form2 and I have a class called Singleton1.

I created an instance of Singleton1 in form1 called obTest:

 Singeton1 obTest = Singleton1.Instance;

From here I need to access the variable "obTest" from form2. Is it possible to do this? How I can access that variable without creating a new Singleton1 variable?

Thanks in advance.

回答1:

If your Instance method is written correctly, then you should be able to call it again in Form2 and get a reference to the exact same object that was created in Form1.



回答2:

Why are you worried about creating a new reference to the Singleton1 object? That's the point of a Singleton, that you only have one!



回答3:

Like so... you just need to make sure you import the namespace on both forms for your singleton class.

NOTE: There are 3 classes in this example - two of which are there to represent your forms.

    /// <summary>
    /// Singleton class
    /// </summary>
    public class Test
    {
        private static Test _instance;

        public static Test Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new Test();
                }

                return _instance;
            }
        }

        public string Data {get;set;}
    }

    /// <summary>
    /// Form A
    /// </summary>
    public class FormA()
    {
        public FormA()
        {
            //Put some data in the 'Data' property of the singleton
            Test.Instance.Data = "value";
        }
    }

    /// <summary>
    /// Form B
    /// </summary>
    public class FormB()
    {
        public FormB()
        {
            //Get the data form the 'Data' property of the singleton
            string value = Test.Instance.Data;
        }
    }


回答4:

Assuming that Singleton1.Instance looks like this in your implementation:

private static Singleton1 _instance;
public static Singleton1 Instance {
    get {
        if(_instance == null)
            _instance = new Singleton1();

        return _instance;
    }
}

you can safely call Singleton1.Instance from both your form1 and form2 classes as they will both be calling the same instance of the Singleton1 object.

If I create a variable in form1 like so: var oBTest = Singleton1.Instance it will give me a reference that will be pointing to the static instance of the Singleton1 object created in the above implementation. If I then create another variable in form2 like this: var oBTestForm2 = Singleton1.Instance it will also be pointing to the same static reference as the variable created in form1.

Hope that helps,

James



回答5:

You would create a new variable, but it's still just a reference to the singleton object (if you created the singleton correctly that is).

Calling Singleton1.Instance multiple times will all result in the same reference, infact, that's the whole purpose of a singleton.



回答6:

Forget the obTest variable. Use Singleton1.Instance. If you are worried about producing invalid results, then your singleton is implemented incorrectly.



回答7:

Yes, assuming this is what's in your form1

private Singeton1 obTest = Singleton1.Instance;

public Singeton1 GetSingletonInstance()
{
    return obTest;
}

then from form2 you can do this to get the singleton object without creating a new one

Singeton1 theObject = form1.GetSingletonInstance();


回答8:

I'm not 100% sure what you are getting at, a new Singleton1 variable (in the sense that it creates another singleton) is not really possible, by definition of what a Singleton is supposed to enforce for your system. A new variable which points to a singleton is certainly possible, you can make as many as you want to point to the instance.

Typically Singleton1.Instance just returns a references to the one and only singleton instance, and obTest is simply a variable which references that object. The overhead of doing var x = Singleton1.Instance to get a quicker handle on the instance any time you need it is minimal, and avoids polluting the global namespace.

I would avoid making static var TheInstance = Singleton1.Instance, since Singleton1.Instance is already presumably in static scope.

If you need a good Singleton implementation, here's mine:

https://stackoverflow.com/a/1010662/18255

public class SingletonBase<T> where T : class
{
    static SingletonBase()
    {
    }

    public static readonly T Instance = 
        typeof(T).InvokeMember(typeof(T).Name, 
                                BindingFlags.CreateInstance | 
                                BindingFlags.Instance |
                                BindingFlags.Public |
                                BindingFlags.NonPublic, 
                                null, null, null) as T;
}

Declare your Singleton1 as this and you are done:

public class Singleton1 : SingletonBase<Singleton1> {
}

This is threadsafe (unlike most, including the one given here) and lazily instantiated.



标签: c# singleton