2

この例のように、プログラムの存続期間中、モジュール内の変数がどこで初期化されるのか疑問に思いました。

Module Helper
    Friend m_Settings As New UserSettings()

    Sub Foo()
        '...
    End Sub

    Sub Bar()
        '...
    End Sub

End Module

Public Class UserSettings
    Public Property UserName As String
    Public Property PrefServer As Integer

    Public Sub New()
        '...
    End Sub

    Public Sub LoadSettings()
        '...
    End Sub
End Class

いつm_Settings初期化されますか?のコンストラクターにブレークポイントを設定UserSettingsして呼び出しスタックを確認することはできますが、そこに「外部コード」が表示されますが、それではあまりわかりません。

4

1 に答える 1

9

CLRはVB.NETモジュールを直接サポートしていないため、すべてのメソッドと変数が型の一部である必要があります。したがって、VB.NETコンパイラは実際に内部でクラスを生成します。モジュールに記述したすべての関数は、そのクラスの静的メソッドになります。モジュールで宣言したすべての変数は、クラスの静的フィールドになります。

モジュールで初期化される変数により、静的コンストラクターが生成されます。そして、初期化コードはこのコンストラクターに移動されます。

これでCLRルールが適用されます。ジッターがこのクラスのメンバーのいずれかに触れるとすぐに、CLRは静的コンストラクターを実行します。次に、すべてのモジュール変数を初期化します。これが、コールスタックに[外部コード]が表示される理由でもあります。コールはCLR内で発信されました。

これに問題が発生することはめったにありません。CLRの静的コンストラクターの保証は非常に強力です。唯一のトリッキーな事故は、例外がスローされる原因となる変数初期化子です。それは内臓が現れ始める時です。スタックトレースは、ソースコードに存在しないコードを示しているため、かなり神秘的です。スローされる実際の例外はTypeInitializationExceptionであり、型を記述しなかったため非常に神秘的です。本当の理由を見つけるには、そのInnerExceptionを調べる必要があります。

于 2013-01-16T21:01:04.307 に答える