11

次のクラスがあるとします。

public class Foo {
    static Foo() {
        Console.WriteLine("Foo is being constructed");
    }
}

public class Bar {
    public void ReferenceFooAsGenericTypeParameter<T>() {
        Console.WriteLine("Foo is being referenced as a generic type parameter");
    }
}

public class SampleClass
{
    public static void Main()
    {
        new Bar().ReferenceFooAsGenericTypeParameter<Foo>();
    }
}

出力は

Foo はジェネリック型パラメーターとして参照されています

仕様によると、これは理にかなっています。

最初のインスタンスが作成される前、または静的メンバーが参照される前に、クラスを初期化するために静的コンストラクターが自動的に呼び出されます。

しかし、型がジェネリック型パラメーターとして参照されているときに静的コンストラクターが呼び出されないのはなぜでしょうか。

4

3 に答える 3

6

なぜそうする必要があるのでしょうか?

通常呼び出される静的コンストラクターのポイントは、静的コンストラクター内に設定された状態が最初に使用される前に初期化されていることを確認することです。

型引数として使用Fooするだけでは、その中の状態は使用されないため、静的コンストラクターを呼び出す必要はありません。

副作用のある静的変数初期化子(たとえば、コンソールに出力するメソッド呼び出し)を作成し、静的コンストラクターを削除してみてください。これは、場合によっては初期化のタイミングに大きな影響を与える可能性があります。ここでトリガーされる可能性があります。

于 2012-08-08T22:10:13.900 に答える
1

これは、ジェネリック型パラメーターとして含めるだけでは、型の内容を意味のある方法で実際に使用できないためです。型には、静的コンストラクターが呼び出されることを保証するために何かを行う必要があります。

そして、これが仕様に沿っていることは正しいです。セクション 10.12 (静的コンストラクター) には次のように記載されています。

静的コンストラクターの実行は、アプリケーション ドメイン内で次のイベントの最初の発生によってトリガーされます。

· クラス タイプのインスタンスが作成されます。

· クラス型の静的メンバーのいずれかが参照されている。

ジェネリック型パラメーターとしての使用は、これらのどちらでもありません。

于 2012-08-08T22:13:45.320 に答える
0

ここで注意すべきことはnew Bar().ReferenceFooAsGenericTypeParameter<Foo>();、タイプ Bar のオブジェクトを作成した場合、メインもバーもインスタンスを作成してFooおらず、そのメンバーのいずれにもアクセスしていないことです。提示されている場合、タイプ自体は単にパラメーターとして渡されています。 .

于 2012-08-08T22:15:09.843 に答える