4

静的コンストラクターとインスタンス コンストラクターを持つ単純なクラスがあります。クラスを初期化すると、静的コンストラクターとインスタンスコンストラクターの両方が呼び出されます。アプリケーション ドメインで一度だけ参照されるのは static だけです。同じクラスの初期化と静的コンストラクターの初期化を再度呼び出すことはできますか? やってみたけど出なかった?クラスでガベージ コレクションを使用した後、main() メソッドで静的コンストラクターを再度呼び出す方法はありますか。

コードは次のとおりです。

public class Employee
{
    public Employee()
    {
        Console.WriteLine("Instance constructor called");   
    }

    static Employee()
    {
        Console.WriteLine("Static constructor called");   
    }

    ~Employee()
     {
        //Dispose();
     }
}

メインメソッド呼び出しで:

static void Main(string[] args)
{
    Employee emp = new Employee();
    Employee emp = new Employee();
}

出力:

呼び出された静的コンストラクター 呼び出されたインスタンス コンストラクター 呼び出されたインスタンス コンストラクター

これで、静的は再度呼び出されなくなりました。アプリケーションドメインで一度呼び出されるためです。しかし、アプリケーション ドメインをアンロードせずに再度呼び出す方法はありますか。ここで GC クラスを使用できますか?

ありがとう。パル

4

3 に答える 3

8

リフレクションを使用しない限り、静的コンストラクター (または、より一般的には型初期化子) は、AppDomain ごとに具象クラスごとに 1 回だけ実行されます。

ジェネリックの場合、異なる型引数を使用すると、異なる具象クラスが得られることに注意してください。

public class Foo<T>
{
    Foo()
    {
        Console.WriteLine("T={0}", typeof(T));
    }
    public static void DummyMethod() {}
}
...
Foo<int>.DummyMethod(); // Executes static constructor first
Foo<string>.DummyMethod(); // Executes static constructor first
Foo<string>.DummyMethod(); // Type is already initialized; no more output
于 2010-09-03T12:17:43.120 に答える
2

ありえない。CLR は、型初期化子が開始されたかどうかを追跡する内部ステータス ビットを保持します。再実行できません。そのステータス ビットは、実際には AppDomain 状態の一部としてローダー ヒープに格納されます。回避策は簡単です。クラスに静的メソッドを追加するだけです。

于 2010-09-03T13:33:24.143 に答える
1

コンストラクターのポイントは、物事を望ましい初期の有効な状態にすることです。

インスタンスコンストラクターは、インスタンスを初期の有効な状態にします。

引数を取るインスタンスコンストラクターは、インスタンスをその引数を反映する初期の有効な状態にします。

静的コンストラクターは、型を初期の有効な状態にします。たとえば、クラスの静的メソッドによって使用される、またはすべてのインスタンスによって共有される静的メンバーを初期化します。

理想的には、すべてのメソッドがオブジェクトと型を有効な状態のままにしますが、コンストラクターは、そもそもそれを1つにする責任があるという点で異なります。

したがって、コンストラクターを2回呼び出そうとするのは間違いです。これは、「コンストラクターを最初の有効な状態に戻す」ことは論理的に2回実行できることではないためです(「initial」と「again」は同じ句ではうまく機能しません)。 。私たちはコンパイラー(コンパイルを拒否する)と言語(これを表現する方法がない)によってそのようなことをするのを助けられます。

そして、論理的に不可能であるため、実際にやりたいことではありません(まあ、3辺以上の三角形を描きたいと思うかもしれませんが、私がやったと言っているだけです)。これは、コンストラクターを使用して、初期の有効な状態を設定する以外のことを行っていることを示しています。

コンストラクターでそのような有効な状態を確立する以外のことを行うことは、せいぜい最適化であり、非常に多くの場合、重大な設計上の欠陥であり、おそらく(より長く修正されないため、さらに悪いことに)最適化が試みられます。本当に深刻な設計上の欠陥。

最適化の試みが実際には設計上の欠陥であることを示す1つの兆候は、静的コンストラクターを複数回呼び出すか、同じオブジェクトでインスタンスコンストラクターを複数回呼び出したいという要望です。

目的の繰り返し可能な動作を特定し、それを別のメソッドに移動して、必要に応じてコンストラクターと他の場所の両方から呼び出します。次に、デザインのロジックを再確認します。これは、クラスデザインで見つけるのは非常に重大な間違いであり、より深刻な問題があることを示唆しているためです。

于 2010-09-03T13:42:45.893 に答える