編集-一貫性のない不完全なテストは私の側の間違った答えにつながりました、そして明確で簡潔で正しい答えの利益のために、この投稿は完全に更新されました。
静的コンストラクターと非静的コンストラクターの違い:
静的コンストラクターは、オブジェクトを最初に使用する前に自動的に呼び出されます。目的は、それ自体のインスタンス化が発生する前に、それ自体の静的フィールド/プロパティ/オブジェクト(など)を設定することです。したがって、静的コンストラクターを持つようにクラスAを定義し、Aのインスタンスを作成すると、静的コンストラクターはAがインスタンス化される前に実行されます。
たとえば、Aの2つのインスタンスを作成するとしますが、Aの静的コンストラクターは1回しか表示されません...なぜ!?静的構築は、特定のオブジェクトタイプに対して1回だけ発生する必要があるためです。それを超えて、それはすでに行われているので、静的な構築を実行する意味はありません!
この演習では、次のコードを検討してください。
public class A
{
static A()
{
Console.WriteLine("Hello from static A");
}
public A()
{
Console.WriteLine("Hello from non-static A");
}
}
public class B : A
{
static B()
{
Console.WriteLine("Hello from static B");
}
public B() : base() //explicit so you know B() will call A()
{
Console.WriteLine("Hello from non-static B");
}
}
次のAのインスタンス化とその結果について考えてみます。
class Program
{
static void Main(string[] args)
{
A instance_1 = new A();
Console.Read();
}
}
結果: 静的Aからこんにちは、非静的Aからこんにちは
この場合、Aは1回インスタンス化されるため、静的Aが呼び出され、次に非静的Aが呼び出されます。
次のA(x2)のインスタンス化とその結果について考えてみます。
class Program
{
static void Main(string[] args)
{
A instance_1 = new A();
A instance_2 = new A();
Console.Read();
}
}
結果: 静的Aからのこんにちは、非静的Aからのこんにちは、非静的Aからのこんにちは
Aが2回インスタンス化されると、静的Aが1回呼び出され(静的Aは1回限りの操作であるため)、非静的Aが2回呼び出されて、Aの2つのインスタンスが作成されます。
Aから割り当てられたBの次のインスタンス化とその結果について考えてみます。
class Program
{
static void Main(string[] args)
{
A instance_1 = new B();
Console.Read();
}
}
結果: 静的Bからのハロー、静的Aからのハロー、非静的Aからのハロー、非静的Bからのハロー
BはAの子孫であるため、AとBの両方が静的に構築されています(初回のみ)。これは、Aが祖先またはBであるため、非静的Bが非静的Aを呼び出すことからも明らかです。
最後に、この例を検討してください...
class Program
{
static void Main(string[] args)
{
A instance_1 = new B();
B instance_2 = new B();
Console.Read();
}
}
結果: 静的Bからのハロー、静的Aからのハロー、非静的Aからのハロー、非静的Bからのハロー、非静的Aからのハロー、非静的Bからのハロー
繰り返しますが、AとBは静的に構築されます(1回のみ)が、非静的Aと非静的BはBの2つのインスタンスであるため繰り返されます。したがって、非静的構築はオブジェクトの新しいインスタンスごとに発生します。
継承における静的構築と非静的構築の呼び出しは、互いに逆の方法で機能するように見えることにも注意する価値があるかもしれません。最後の例のIEでは、静的Bは静的Aの前に呼び出されますが、非静的Aは非静的Bの前に呼び出されます。