2011-11-14 9 views
0

リストを継承:シングルトンは、私はこのような私のクラスを構造化<T>

public class MyList: List<MyClass> 
{ 
    internal static bool isConfigured; 

    // singleton 
    public MyList() 
    { 
     if (!MyList.isConfigured) 
     { 
      lock ("isConfigured") 
      { 
       if (!MyList.isConfigured) 
       { 
        // add some elements to MyList parsing them from an XML 
        [..] 

        MyList.isConfigured = true; 
       } 
      } 
     } 
    } 

    public static MyClass MyStaticMethod(int argument) 
    { 
     foreach (MyClass c in new MyList()) 
     { 
      // do something 
     } 
     return // an instance of MyClass 
    } 

} 

を私はシングルトン外からMyList.MyStaticMethod()を呼び出すと、私は次の例外を取得:

[..] 
MyClass mc = MyList.MyStaticMethod(1)); 
[..] 

An object reference is required for the non-static field, method, or property 'MyList.get' 

どのようにすることができますこの問題を解決します? Listに基づいてシングルトンクラスを作る理由は何ですか?ありがとう

+2

書かれたように、コード*基本的に*コンパイルして実行されます。そのエラーを起こしているコード行は何ですか?私は、エラーのある行がサンプルに含まれているとは思わない。ちょっとしたメモとして、私はそこにシングルトンは見ません。 –

+0

シングルトンが必要ない場合は、[Lazy ](http://msdn.microsoft.com/en-us/library/dd642331)を参照してください。aspx) –

+0

を編集すると表示されます。それはコンパイルされますが、私は外部から呼び出すときにエラーが発生します。 – pistacchio

答えて

5

他のシングルトンと同じです。

エラーメッセージに基づいて
public class MyList: List<MyClass> { 
    private readonly static MyList instance = new MyList(); 

    private MyList() { } 

    public static MyList Instance 
    { 
    get 
    { 
     return instance; 
    } 
    } 
} 
+2

シングルトンとしては信頼できません、btw。 OPのダブルチェック手法や単純なスタティックフィールドイニシャライザなどは、より安全です。 –

+0

@MarcGravellが更新されました。 –

1

オブジェクト参照が非静的フィールド、メソッド、またはプロパティのために必要とされる 'MyList.get'

Iはを考えるこれは単純に名前の衝突が発生した場合です。例:

class Foo { 
    static void Bar() { 
     MyClass mc = MyList.MyStaticMethod(1); // your erroring line 
    } 
    string MyList {get;set;} // the data-type is not important here 
} 
あなたがローカルメンバーMyList対タイプMyListを意味修正がある資格を、その場合には

SomeNamespaceはあなたMyListクラスの名前空間がある、またはそれがルート名前空間である場合

MyClass mc = SomeNamespace.MyList.MyStaticMethod(1); // your erroring line 

MyClass mc = global::MyList.MyStaticMethod(1); // your erroring line 

注:私はこれはかなりのようにしてエラーに得られないことができますが、それは、プロパティアクセサについて話しているという事実は、私に考えさせますこれはおそらく関連している。

+0

なぜ私はMyList.getについて話していたのか分かりませんでした。 :) – Chris

0

継承を使用してsingletonを達成することはできません。 singletonを動作させるには、固定のcompositeフィールドが必要です。

コンストラクタを呼び出すと、実際にはMyListという新しいインスタンスが作成され、staticフィールドのフィールドはisConfiguredになります。

あなたの問題についてのベストプラクティスとしては、MyListのインスタンスにあなたの追加した味を与えるFactory Methodがあります。

IList<T>から実装し、基本的にはstaticリストの種類のリストを使用してください。

public class MyList: IList<MyClass> 
{ 
    private static MyList _myList = null; 

    private MyList() 
    { 

    } 

    //This is the factory method 
    public static MyList GetInstance(int args) 
    { 
     return _myList ?? (_myList = new MyList()); 
    } 

    public IEnumerator<MyClass> GetEnumerator() 
    { 
     return _myList.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

    public void Add(MyClass item) 
    { 
     _myList.Add(item); 
    } 

    public void Clear() 
    { 
     _myList.Clear(); 
    } 

    public bool Contains(MyClass item) 
    { 
     return _myList.Contains(item); 
    } 

    public void CopyTo(MyClass[] array, int arrayIndex) 
    { 
     _myList.CopyTo(array, arrayIndex); 
    } 

    public bool Remove(MyClass item) 
    { 
     return _myList.Remove(item); 
    } 

    public int Count 
    { 
     get { return _myList.Count; } 
    } 

    public bool IsReadOnly 
    { 
     get { return _myList.IsReadOnly; } 
    } 

    public int IndexOf(MyClass item) 
    { 
     return _myList.IndexOf(item); 
    } 

    public void Insert(int index, MyClass item) 
    { 
     _myList.Insert(index, item); 
    } 

    public void RemoveAt(int index) 
    { 
     _myList.RemoveAt(index); 
    } 

    public MyClass this[int index] 
    { 
     get { return _myList[index]; } 
     set { _myList[index] = value; } 
    } 
} 

USAGE

MyList myList = MyList.GetInstance(); 
var myClass = new MyClass(); 
myList.Add(myClass); 
Assert.Equal(myClass, myList[0]); // yields true 
// Now you basically an instance of List<MyClass> 
// and which is singleton. 
関連する問題