9

シングルトンデザインパターンの使用に苦労しています。この単純なコンソールアプリケーションで使用しようとしています。ProgramクラスのMainメソッドに問題があります。次のようなシングルトンクラスからオブジェクトを定義したいのですが、var data = Singleton.Instance;なぜそれができないのかわかりません。また、プログラムを実行したときに次のエラーメッセージが表示される理由もわかりません。

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

では、それを修正する方法は?
シングルトンクラス:

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");

    }
}
}

アップデート:

皆さん、これまでのご協力に心から感謝いたします。プログラムは現在機能していますが、ロジックは機能していません。メインプログラムを見ると、リストには「HelloWorld!!!」しか含まれていないことがわかります。ただし、HasMessageメソッドを使用した場合は機能しません。プログラムは「一致があります」と表示し続けるからです。しかし、「文字列なし!!!」と表示されるはずです。一致するものがないので。では、それを修正する方法は?

4

5 に答える 5

12

フィールドMessagesは何にも初期化されていません。そのため、例外が発生します。あなたのクラスでは:

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

JonSkeetによるスレッドセーフシングルトンの実装もご覧ください。

編集:

更新された質問に基づいています。あなたのチェックとメッセージは反対です。そのはず:

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

HasMessage渡されたパラメーターがリストに存在する場合、メソッドはtrueを返し、そうでない場合はfalseを返します。

于 2013-01-15T04:36:32.520 に答える
4

ただし、HasMessageメソッドを使用した場合は機能しません。プログラムは「一致があります」と表示し続けるからです。しかし、「文字列なし!!!」と表示されるはずです。一致するものがないので。では、それを修正する方法は?

これは実際には別の質問になるはずですが、とにかく答えます。あなたはあなたの状態を逆行させています。インスタンスにメッセージ「12」が含まれている場合は「文字列なし」を記述し、含まれていない場合は「一致があります記述します。これを試して:

    if(Singleton.Instance.HasMessage("12"))
        Console.WriteLine("There is a match");
    else
        Console.WriteLine("NO STRING!!!");
于 2013-01-15T05:51:07.367 に答える
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);
    }
}

このサイトには、デザインパターンに役立つC#チュートリアルがいくつかあります。

于 2013-01-15T05:04:53.777 に答える
1
private List<String> Messages;

これがあなたの問題です。メンバーがコードにインスタンス化されたことはありません。あなたは次のようにすることができます:

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

また、ローカル変数とメンバーには適切な命名規則を使用することをお勧めします。に変更instanceします。また、スレッドセーフな方法でシングルトンを実装してみてください...詳細については、このページを参照してください。m_InstanceMessagesm_Messages

于 2013-01-15T04:40:36.410 に答える
0

これがシングルトンの実装です。

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
于 2016-11-15T13:34:38.107 に答える