1. ホーム
  2. c#

[解決済み] 静的コンストラクタはどのように機能するのですか?

2023-07-26 05:22:41

質問

namespace MyNameSpace
{
    static class MyClass
    {
        static MyClass()
        {
            //Authentication process.. User needs to enter password
        }

        public static void MyMethod()
        {
            //Depends on successful completion of constructor
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyClass.MyMethod();
        }
    }
}

以下は、私が想定していたシーケンスです。

  1. 静的コンストラクタの開始
  2. 静的コンストラクタの終了
  3. メイン開始
  4. MyMethodの開始
  5. メイン終了

今、どんなシナリオでも、もし4が2より先に始まったら、私は困ります。可能なのでしょうか?

どのように解決するのですか?

ここで質問したのは一つだけですが、十数個の質問があります。 べきです。 という質問がたくさんありましたので、すべてお答えします。

<ブロッククオート

以下は、私が想定していた順序です。

  1. クラス・コンストラクタの開始 (別名 cctor )
  2. cctorの終了
  3. メイン開始
  4. MyMethodの開始

これは正しいのでしょうか?

いいえ、正しい順序は

  1. Program の Cctor の開始(ある場合)。ありません。
  2. もしあれば、プログラムの終了。ありません。
  3. メインの開始
  4. MyClassのcctorの開始
  5. MyClassのカクタの終端
  6. MyClass.MyMethodの開始。

静的フィールドイニシャライザがある場合はどうでしょうか?

CLRは、場合によっては静的フィールドイニシャライザの実行順序を変更することが許されています。詳しくはJonのページを参照してください。

静的コンストラクタと型イニシャライザの違い

のような静的メソッドは可能なのでしょうか? MyMethod のような静的メソッドが、そのクラスの Cctor が完了する前に呼び出されることはあるのでしょうか?

はい、そうです。 もしcctor自身がMyMethodを呼び出すなら、明らかにcctorが完了する前にMyMethodが呼び出されるでしょう。

cctorがMyMethodを呼び出すことはありません。のような静的メソッドは可能なのでしょうか? MyMethod のような静的メソッドが、MyClassのcctorが完了する前に呼び出されることはありますか?

はい。 Cctor が MyMethod を呼び出す他の型を使用する場合、MyClass の Cctor が完了する前に MyMethod が呼び出されます。

直接的にも間接的にもMyMethodを呼び出すcctorはありません! のような静的メソッドを呼び出すことは可能でしょうか? MyMethod のような静的メソッドが、MyClass の cctor が完了する前に呼び出されることはあるでしょうか?

いいえ。

<ブロッククオート

複数のスレッドが絡んでいてもそうなのでしょうか?

静的メソッドがどのスレッドでも呼び出される前に、1つのスレッドでcctorが終了します。

cctorは複数回呼び出すことができるのでしょうか?2つのスレッドが両方ともcctorを実行させたとします。

cctorは、何個のスレッドが関与していても、せいぜい一度だけ呼ばれることが保証されています。もし2つのスレッドが同時にMyMethod "を呼び出すと、それらはレースになります。一方はレースに負け、勝ったスレッドで MyClass cctor が完了するまでブロックされます。

負けたスレッドは ブロック が終了するまで? 本当に ?

本当に。

<ブロッククオート

にあるcctorはどうなるんだ? 勝利 スレッド上の cctor が、以前に 負けた によって取られたロックをブロックするコードを呼び出しますか?

すると、古典的なロック順序の逆転の状態が発生します。あなたのプログラムはデッドロックします。永遠に。

それは危険な気がします。どうすればデッドロックを回避できるのでしょうか?

それをやると痛いというのであれば それをやめてください . cctorでブロックできるようなことは絶対にしないでください。

複雑なセキュリティ要件を強制するために、cctorの初期化セマンティクスに依存するのは良い考えでしょうか?また、ユーザーとのインタラクションを行うcctorを持つことは良い考えでしょうか?

どちらも良いアイデアではありません。私のアドバイスは、あなたのメソッドのセキュリティに影響を与える前提条件が満たされることを保証するために、別の方法を見つけるべきだということです。