静的コンストラクター (C# プログラミング ガイド)Static Constructors (C# Programming Guide)

静的コンストラクターは、任意の static データを初期化するため、または 1 回だけ実行する必要がある特定のアクションを実行するために使います。A static constructor is used to initialize any static data, or to perform a particular action that needs to be performed once only. 最初のインスタンスが作成され前、または静的メンバーが参照される前に、自動的に呼び出されます。It is called automatically before the first instance is created or any static members are referenced.

class SimpleClass
{
    // Static variable that must be initialized at run time.
    static readonly long baseline;

    // Static constructor is called at most one time, before any
    // instance constructor is invoked or member is accessed.
    static SimpleClass()
    {
        baseline = DateTime.Now.Ticks;
    }
}

解説Remarks

静的コンストラクターには、次の特徴があります。Static constructors have the following properties:

  • 静的コンストラクターはアクセス修飾子を取らず、パラメーターはありません。A static constructor does not take access modifiers or have parameters.

  • クラスまたは構造体は、静的コンストラクターを 1 つだけ持つことができます。A class or struct can only have one static constructor.

  • 静的コンストラクターを継承またはオーバーロードすることはできません。Static constructors cannot be inherited or overloaded.

  • 静的コンストラクターは、直接呼び出すことはできず、共通言語ランタイム (CLR) によって呼び出されることだけが意図されています。A static constructor cannot be called directly and is only meant to be called by the common language runtime (CLR). 自動的に呼び出されます。It is invoked automatically.

  • ユーザーは、プログラムで静的コンストラクターが実行されるタイミングを制御できません。The user has no control on when the static constructor is executed in the program.

  • 静的コンストラクターは、最初のインスタンスが作成され前、または静的メンバーが参照される前に、クラスを初期化するために自動的に呼び出されます。A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced. 静的コンストラクターは、インスタンス コンストラクターの前に実行されます。A static constructor will run before an instance constructor. イベントまたはデリゲートに割り当てられている静的メソッドが呼び出されるときは型の静的コンストラクターが呼び出されますが、割り当てられるときは呼び出されないことに注意してください。Note that a type's static constructor is called when a static method assigned to an event or a delegate is invoked and not when it is assigned. 静的フィールド変数初期化子が静的コンストラクターのクラスに存在する場合、初期化子は、静的コンストラクターの実行の直前に、クラス宣言に出現するテキストの順序で実行されます。If static field variable initializers are present in the class of the static constructor, they will be executed in the textual order in which they appear in the class declaration immediately prior to the execution of the static constructor.

  • 静的フィールドを初期化するための静的コンストラクターを提供しないと、すべての静的フィールドは、「既定値の一覧表」で示されている既定値に初期化されます。If you don't provide a static constructor to initialize static fields, all static fields are initialized to their default value as listed in the Default Values Table.

  • 静的コンストラクターが例外をスローした場合、ランタイムがその静的コンストラクターを再度呼び出すことはなく、その型は、プログラムが実行しているアプリケーション ドメインの有効期間中、初期化されないままになります。If a static constructor throws an exception, the runtime will not invoke it a second time, and the type will remain uninitialized for the lifetime of the application domain in which your program is running. ほとんどの場合、静的コンストラクターで型をインスタンス化できないとき、または静的コンストラクター内でハンドルされない例外が発生したときは、TypeInitializationException 例外がスローされます。Most commonly, a TypeInitializationException exception is thrown when a static constructor is unable to instantiate a type or for an unhandled exception occurring within a static constructor. ソース コードで明示的に定義されていない暗黙的な静的コンストラクターでは、トラブルシューティングの際に中間言語 (IL) のコードを調べることが必要になる場合があります。For implicit static constructors that are not explicitly defined in source code, troubleshooting may require inspection of the intermediate language (IL) code.

  • 静的コンストラクターが存在すると、BeforeFieldInit 型属性を追加できません。The presence of a static constructor prevents the addition of the BeforeFieldInit type attribute. これにより、ランタイムの最適化が制限されます。This limits runtime optimization.

  • static readonly として宣言されているフィールドは、その宣言の一部として、または静的コンストラクター内でのみ、割り当てることができます。A field declared as static readonly may only be assigned as part of its declaration or in a static constructor. 明示的な静的コンストラクターが必要ない場合は、ランタイムのより適切な最適化のため、静的コンストラクターではなく、宣言時に静的フィールドを初期化します。When an explicit static constructor is not required, initialize static fields at declaration, rather than through a static constructor for better runtime optimization.

注意

直接アクセスすることはできませんが、初期化の例外のトラブルシューティングを助けるため、明示的な静的コンストラクターが存在することを文書化する必要があります。Though not directly accessible, the presence of an explicit static constructor should be documented to assist with troubleshooting initialization exceptions.

使用法Usage

  • 静的コンストラクターの一般的な用途は、クラスがログ ファイルを使っていて、このファイルにエントリを書き込むためにコンストラクターが使われる場合です。A typical use of static constructors is when the class is using a log file and the constructor is used to write entries to this file.

  • コンストラクターが LoadLibrary メソッドを呼び出すことができる場合は、アンマネージ コードのラッパー クラスを作成するときにも静的コンストラクターが役に立ちます。Static constructors are also useful when creating wrapper classes for unmanaged code, when the constructor can call the LoadLibrary method.

  • 静的コンストラクターは、制約 (型パラメーターの制約) によりコンパイル時にチェックできない型パラメーターに対して、実行時にチェックを強制するのに適した場所でもあります。Static constructors are also a convenient place to enforce run-time checks on the type parameter that cannot be checked at compile-time via constraints (Type parameter constraints).

Example

この例では、Bus クラスに静的コンストラクターがあります。In this example, class Bus has a static constructor. Bus の最初のインスタンスが作成されるとき (bus1)、静的コンストラクターが呼び出されてクラスが初期化されます。When the first instance of Bus is created (bus1), the static constructor is invoked to initialize the class. サンプルの出力では、Bus のインスタンスが 2 つでも静的コンストラクターは 1 回だけ実行されること、およびインスタンス コンストラクターの実行前に静的コンストラクターが実行されることがわかります。The sample output verifies that the static constructor runs only one time, even though two instances of Bus are created, and that it runs before the instance constructor runs.

 public class Bus
 {
     // Static variable used by all Bus instances.
     // Represents the time the first bus of the day starts its route.
     protected static readonly DateTime globalStartTime;

     // Property for the number of each bus.
     protected int RouteNumber { get; set; }

     // Static constructor to initialize the static variable.
     // It is invoked before the first instance constructor is run.
     static Bus()
     {
         globalStartTime = DateTime.Now;

         // The following statement produces the first line of output, 
         // and the line occurs only once.
         Console.WriteLine("Static constructor sets global start time to {0}",
             globalStartTime.ToLongTimeString());
     }

     // Instance constructor.
     public Bus(int routeNum)
     {
         RouteNumber = routeNum;
         Console.WriteLine("Bus #{0} is created.", RouteNumber);
     }

     // Instance method.
     public void Drive()
     {
         TimeSpan elapsedTime = DateTime.Now - globalStartTime;

         // For demonstration purposes we treat milliseconds as minutes to simulate
         // actual bus times. Do not do this in your actual bus schedule program!
         Console.WriteLine("{0} is starting its route {1:N2} minutes after global start time {2}.",
                                 this.RouteNumber,
                                 elapsedTime.Milliseconds,
                                 globalStartTime.ToShortTimeString());
     }
 }

 class TestBus
 {
     static void Main()
     {
         // The creation of this instance activates the static constructor.
         Bus bus1 = new Bus(71);

         // Create a second bus.
         Bus bus2 = new Bus(72);

         // Send bus1 on its way.
         bus1.Drive();

         // Wait for bus2 to warm up.
         System.Threading.Thread.Sleep(25);

         // Send bus2 on its way.
         bus2.Drive();

         // Keep the console window open in debug mode.
         System.Console.WriteLine("Press any key to exit.");
         System.Console.ReadKey();
     }
 }
 /* Sample output:
     Static constructor sets global start time to 3:57:08 PM.
     Bus #71 is created.
     Bus #72 is created.
     71 is starting its route 6.00 minutes after global start time 3:57 PM.
     72 is starting its route 31.00 minutes after global start time 3:57 PM.      
*/

C# 言語仕様C# language specification

詳しくは、C# 言語仕様の「Static constructors (静的コンストラクター)」セクションをご覧ください。For more information, see the Static constructors section of the C# language specification.

関連項目See also