2011-12-22 11 views
3

私は、単一のスタティックフィールドを持つ単純なベースクラスを持っています。私は、この基本クラスから派生した多数のクラスを持っています。派生クラスを作成すると、静的フィールドを初期化する基本クラスstatic ctorの呼び出しが発生します(期待通りに動作します)。問題は、別の派生クラスを作成して同じベースから継承すると、ベースの静的フィールドがまだヌルであることです。それは私がインスタンス化した最初のクラスによって初期化されました。スタティックフィールドのライフタイム(ベースクラス)

基本クラスの静的フィールドにはグローバル割り当てがあり、すべての派生クラスに表示(共有)しないでください。

マイモデル:

class Base<T> 
{ 

protected static object s_field = null; 

static Base { s_field = new object(); } 
} 

class Derived1<T> : Base<T> 
{ 

} 

class Derived2<T> : Base<T> 
{ 

} 

// ... later in the program 

Derived1<int> instance1 = new Derived1<int>(); // initializes static field (s_field in base class) for all derived types 

Derived2<double> instance2 = new Derived2<double>(); // the static field is null 

(私は、デバッガを介してこれを見ることができますが、それはすでに前の行??によって初期化されていないはずです)

+1

タイトルに「C#.net - 」というプレフィックスを付けないでください。それがタグのためのものです。 –

+0

@ActiveXこれはプログラムで実行できる唯一の実行行ですか?静的フィールドがヌルに設定されている 'instance1'のインスタンス化と、instance2'オブジェクトがヌル値を持つように見える間のどこかで可能でしょうか?これは、2つのオブジェクトを同時に比較することによって、検証される可能性があります。一方がnullで他方がそうでない場合は、何かを残しておきます。 –

+3

そうでしょう。私はあなたのスニペットを試して、静的フィールドはnullではありません。だからこそ、あなたが見ているものは、その原因はここに掲載されたコードにはありません –

答えて

2

あなたのコードを変更したので、私はあなたを信じてジェネリックスが.NETでどのように機能するかを理解する必要があります。

ジェネリックの静的な動作は、通常の場合とは少し異なります。あなたが提供するユニークな公開タイプTごとに、基本クラスは一意の静的メンバー値を保持します。

あなたはその後、youllのは、私が何を言っているかのコンセプトを参照してください>派生<ダブル経由オープンタイプ同じ基底クラスのための二重の別のインスタンスを作成します。ここで

より明確に示すために、サンプルコード:

ここ
public class Base<T> 
    { 
     public static string str = null; 

     static Base() 
     { 
      str = "hello"; 

      Console.WriteLine("Ctor cald"); 
     } 
    } 

    public class Derived1<T> : Base<T>{} 
    public class Derived2<T> : Base<T> { } 

    public partial class Program 
    { 
     public static void Main() 
     { 
      Derived1<int> derv = new Derived1<int>(); 
      Derived2<double> derv2 = new Derived2<double>(); 
      Derived2<double> derv3 = new Derived2<double>(); 


      Console.ReadKey(); 
     }  
    } 

あなたは静的CTORのための唯一の2の呼び出しを見るであろう。

1

私は間違いを知った!うわー、基本クラスは実際にはテンプレートクラス:Base<T>です。このような基底のオブジェクトを作成すると、new Derived<int>()new Derived<double>()new Derived<object>()は完全に異なるタイプなので、静的フィールドのルールは異なります。静的フィールドはTタイプのファミリーに割り当てられます。 これを反映するために上記の例(最初の投稿)。

+0

FYI、あなたは山括弧を引用する必要があります。コードを選択し、Control-Kを押します。私はあなたのためにこれをしました。 –

0

画像にジェネリックスを入れると全体の質問が変わります。静的メンバーの継承に関する理解は、ジェネリックスなしでは期待通りに機能し、ジェネリックスが配置されている場合でも、ジェネリックスは実行時に異なるタイプを作成するという点を除いて有効です。 Base<int>Derived1<int>は、スタティックメンバーを共有しない実行時にBase<int>と異なるタイプのDerived1<decimal>と同じスタティックメンバーを共有します。

関連する問題