如何在C#中使用这个Singleton类?

时间:2013-01-15 04:33:58

标签: c# design-patterns

我正在努力使用Singleton设计模式。我试图在这个简单的控制台应用程序中使用它。我在Program类的Main方法中遇到了问题。我想从Singleton类中定义对象,例如:var data = Singleton.Instance;,但我不知道为什么我不能这样做 此外,我不知道为什么我在运行程序时收到以下错误消息:

Unhandled Exception: System.NullRefernceException: Object reference not 
  set to an instance of an object.

那么如何解决?
Singleton类:

namespace Singleton
{
    class Singleton
    {
        //Variable
        private static Singleton instance;
        private List<string> Messages;
        //Constructor
        private Singleton() { }
        //Property
        public static Singleton Instance
        {
            get 
            {
                if (instance == null)
                {
                    instance = new Singleton();
                }
                return instance;
            }
        }
        //Methods
        public void Message(string message)
        {
            Messages.Add(message);
        }

        public bool HasMessage(string message)
        {
            return Messages.Contains(message);
        }
    }
}

计划类:

namespace Singleton
{
    class Program
{
    static void Main(string[] args)
    {
        var data = Singleton.Instance;
        Singleton.Instance.Message("Hello World!!!");
        if(Singleton.Instance.HasMessage("12"))
            Console.WriteLine("NO STRING!!!");
        else
            Console.WriteLine("There is a match");

    }
}
}

更新

伙计们,我非常感谢你们的帮助。该程序现在正在运行,但逻辑不起作用。如果查看主程序,您会看到列表中只有“Hello World !!!”。但是,当我使用HasMessage方法时不起作用。因为程序一直显示“有匹配”。但它应该告诉我“没有STRING !!!”因为没有比赛。 那么如何解决这个问题?

5 个答案:

答案 0 :(得分:12)

您的字段Messages未初始化为任何内容。这就是你得到例外的原因。在你的班上做:

 private List<string> Messages = new List<string>();

您还可以查看Thread Safe Singleton implementation by Jon Skeet

修改

基于更新的问题。您的支票和信息正好相反。它应该是:

if (Singleton.Instance.HasMessage("12"))
    Console.WriteLine("There is a match");
else
    Console.WriteLine("NO STRING!!!");

如果传递的参数出现在列表中,则方法HasMessage返回true,否则返回false。

答案 1 :(得分:4)

看起来你几乎就在那里。考虑重写你的代码:

class Singleton
{
    //Variable
    private static Singleton Instance;
    private List<string> Messages;
    //Constructor
    private Singleton() 
    {
     Messages = new List<string>(); //Make sure to instantiate instance types before use. 
    }
    //Property
    public static Singleton GetInstance()
    {
            if (Instance == null)
            {
                Instance = new Singleton();
            }
            return Instance;

    }
    //Methods
    public void Message(string message)
    {
        Messages.Add(message);
    }

    public bool HasMessage(string message)
    {
        return Messages.Contains(message);
    }
}

这个site的设计模式有一些有用的C#教程。

答案 2 :(得分:4)

  

但是,当我使用HasMessage方法时不起作用。因为程序一直显示“有匹配”。但它应该告诉我“没有STRING !!!”因为没有比赛。 那么如何解决这个问题?

这应该是一个单独的问题,但无论如何我都会回答它。你的状况倒退了。如果实例 包含消息“12”,则表示编写“无字符串”,如果,则表示“匹配”。试试这个:

    if(Singleton.Instance.HasMessage("12"))
        Console.WriteLine("There is a match");
    else
        Console.WriteLine("NO STRING!!!");

答案 3 :(得分:1)

private List<String> Messages;

这是你的问题。该成员从未在您的代码中实例化。你可以这样做:

    //Constructor
    private Singleton()
    {
        Messages = new List<string>();
    }

另外,我建议您为本地变量和成员使用正确的命名约定。将instance更改为m_Instance,将Messages更改为m_Messages。还尝试以线程安全的方式实现单例...有关更多信息,请查看this page

答案 4 :(得分:0)

这是Singleton的实现:

public sealed class SingletonExample
{
    //static Field
    private static SingletonExample _seInstance = null;
    private int _nCounter = 0;

    // private constructor
    private SingletonExample() { _nCounter = 1; }

    //public static get(), with creating only one instance EVER
    public static SingletonExample SeInstance
    { 
        get { return _seInstance ?? (_seInstance = new SingletonExample()); }
    }      
}

如何调用和创建实例?

SingletonExample si1 = SingletonExample.SeInstance;
SingletonExample si2 = SingletonExample.SeInstance; // it will be the same object

System.Diagnostics.Debug.WriteLine(si1.Equals(si2));// TRUE