静的コンストラクタの使い方を教えてください。いつ、いつ、静的コンストラクタを作成するのですか。
いいえ、あなたはそれをオーバーロードすることはできません。静的コンストラクタは、型に関連付けられた静的フィールド(または他の型ごとの操作)を初期化するのに役立ちます。特に、必要な構成データを読み取り専用フィールドなどに読み込むのに役立ちます。
それは、それが最初に必要とされるときにランタイムによって自動的に実行されます(そこでの正確な規則は複雑で( "beforefieldinit"を見てください)、そしてCLR2とCLR4の間で微妙に変更されます)。リフレクションを悪用しない限り、最大でを一度に実行することが保証されています(たとえ2つのスレッドが同時に到着したとしても)。
From 静的コンストラクタ(C#プログラミングガイド) :
静的コンストラクタは、静的データを初期化するため、または1回だけ実行する必要がある特定のアクションを実行するために使用されます。最初のインスタンスが作成されるか、静的メンバーが参照される前に自動的に呼び出されます。
静的コンストラクタには次の特性があります。
静的コンストラクタは、アクセス修飾子を取ったりパラメータを持ったりしません。
最初のインスタンスが作成される前、または静的メンバーが参照される前に、静的コンストラクターが自動的に呼び出されてクラスを初期化します。
静的コンストラクタは直接呼び出すことはできません。
ユーザーは、プログラム内で静的コンストラクターをいつ実行するかを制御できません。
静的コンストラクタの一般的な用途は、クラスがログファイルを使用していて、このファイルにエントリを書き込むためにコンストラクタが使用されている場合です。
静的コンストラクタは、アンマネージコード用のラッパークラスを作成するとき、コンストラクタが
LoadLibrary
メソッドを呼び出すことができるときにも役立ちます。
静的コンストラクタは、初期化の順序が重要になるように相互に依存する静的フィールドがある場合にも非常に便利です。フィールドの順序を変更するフォーマッタ/ビューティファイヤを通してコードを実行すると、期待していなかった場所にnull値が表示されることがあります。
例:このクラスがあるとします。
class ScopeMonitor
{
static string urlFragment = "foo/bar";
static string firstPart= "http://www.example.com/";
static string fullUrl= firstPart + urlFragment;
}
fullUr
にアクセスすると、 " http://www.example.com/foo/bar "になります。
数ヵ月後、コードを整理してフィールドをアルファベット順に並べます(それらがはるかに大きいリストの一部であるとしましょう。そのため、問題に気付くことはありません)。あなたが持っている:
class ScopeMonitor
{
static string firstPart= "http://www.example.com/";
static string fullUrl= firstPart + urlFragment;
static string urlFragment = "foo/bar";
}
fullUrl
が設定されていた時点ではurlFragment
が初期化されていなかったため、fullUrl
の値は " http://www.example.com/ "になりました。良くない。そのため、初期化の面倒を見るために静的コンストラクタを追加します。
class ScopeMonitor
{
static string firstPart= "http://www.example.com/";
static string fullUrl;
static string urlFragment = "foo/bar";
static ScopeMonitor()
{
fullUrl= firstPart + urlFragment;
}
}
今、あなたがどんな順序でフィールドを持っていようとも、初期化は常に正しいでしょう。
1.クラスの静的メンバーにのみアクセスできます。
理由:非静的メンバがオブジェクトインスタンスに固有のものです。静的コンストラクタが非静的メンバに対して動作することを許可されている場合、それはすべてのオブジェクトインスタンスの変更を反映しますが、これは実用的ではありません。
2.静的コンストラクタにはパラメータを指定しないでください。
理由:CLRから呼ばれることになるので、だれもパラメータを渡すことができません。 3.静的コンストラクタは1つだけ許可されています。
理由:オーバーロードでは、静的コンストラクターでは不可能なメソッド/コンストラクター定義の観点から、2つのメソッドを異ならせる必要があります。
それにアクセス修飾子があってはいけません。
理由:やはり、静的コンストラクターへの呼び出しはオブジェクトではなくCLRによって行われるため、アクセス修飾子を持つ必要はありません。
静的コンストラクタを使用して静的フィールドを初期化できます。これらのフィールドが使用される前に、不定期に実行されます。 Microsoftのドキュメントと多くの開発者は、型の静的コンストラクタはかなりのオーバーヘッドを強いると警告しています。
最大限のパフォーマンスを得るには、静的コンストラクタを避けることが最善です。
更新: 同じクラスで複数の静的コンストラクタを使用することはできませんが、他のインスタンスコンストラクタを(最大)1つの静的コンストラクタで使用することはできます。
いつ、いつ、静的コンストラクタを作成するのでしょうか。
静的コンストラクタを使用する1つの特定の理由は、 'super enum'クラスを作成することです。これは(単純な、人為的な)例です:
public class Animals
{
private readonly string _description;
private readonly string _speciesBinomialName;
public string Description { get { return _description; } }
public string SpeciesBinomialName { get { return _speciesBinomialName; } }
private Animals(string description, string speciesBinomialName)
{
_description = description;
_speciesBinomialName = speciesBinomialName;
}
private static readonly Animals _dog;
private static readonly Animals _cat;
private static readonly Animals _boaConstrictor;
public static Animals Dog { get { return _dog; } }
public static Animals Cat { get { return _cat; } }
public static Animals BoaConstrictor { get { return _boaConstrictor; } }
static Animals()
{
_dog = new Animals("Man's best friend", "Canis familiaris");
_cat = new Animals("Small, typically furry, killer", "Felis catus");
_boaConstrictor = new Animals("Large, heavy-bodied snake", "Boa constrictor");
}
}
他の列挙型と非常によく似ています(構文上)。
Animals.Dog
通常のenum
よりも優れているのは、関連情報を簡単にカプセル化できることです。不利な点の1つは、これらの値をswitch
ステートメントで使用できないことです(これには定数値が必要なため)。
静的コンストラクタ
静的修飾子を使用して宣言されたコンストラクターは静的コンストラクターです。静的コンストラクタは、静的データを初期化するため、またはクラスのライフサイクルの中で一度だけ実行する必要がある特定のアクションを実行するために使用されます。静的コンストラクタは、クラス内で実行される最初のコードブロックです。静的コンストラクタはクラスのライフサイクルの中で一度だけ実行されます。自動的に呼び出されます。静的コンストラクタはパラメータを取りません。アクセス指定子はありません。直接呼び出されません。