3

.NET クラス ローダーが動作する標準的な方法はありますか?

このコードをコンパイルするとします。

Option Strict On : Option Explicit On

Module Module1
    Sub Main()
        System.Diagnostics.Debug.WriteLine("Main")
        Dim g = C.A
    End Sub
End Module

Public Class C
    Shared Sub New()
        System.Diagnostics.Debug.WriteLine("Init C")
    End Sub
    Shared Property A As New A
End Class

Public Class A
    Shared Sub New()
        System.Diagnostics.Debug.WriteLine("Init A")
    End Sub
    Public Sub New()
        System.Diagnostics.Debug.WriteLine("A Constructor")
    End Sub
End Class

コンパイルされたコードが (実装されているすべてのプラットフォームで) 次の出力を持つことを保証できますか?

Main
Init A
A Constructor
Init C
4

2 に答える 2

5

はい、静的コンストラクターとインスタンス コンストラクターを呼び出す順序は、言語仕様の一部です。すべての準拠コンパイラは、このプログラムに対して同じ IL を発行する必要があります。

于 2011-06-11T12:14:36.417 に答える
4

インライン初期化ではなくコンストラクターを使用しているため、VB コンパイラーは型を でマークせずbeforefieldinit、順序は正確に制御されます。

ただし、次のように記述した場合 (インライン初期化を使用):

Option Strict On : Option Explicit On

Module Module1
    Sub Main()
        System.Console.WriteLine("Main")
        Dim g = C.A
    End Sub
End Module
Public Class C
    Shared Function Narg() As A
        Dim alpha As New A
        System.Console.WriteLine("Init C")
        Return alpha
    End Function
    Shared Property A As A = Narg()
End Class
Public Class A
    Shared Sub New()
        System.Console.WriteLine("Init A")
    End Sub
    Public Sub New()
        System.Console.WriteLine("A Constructor")
    End Sub
End Class

順序は指定されません。元のコードと同じ順序が許可されますが、C以前に初期化することができます。実際、私のシステムでは、出力は次のようになります。

Init A
A Constructor
Init C
Main

その理由は、C現在は とマークされているためですbeforefieldinit


いいえ、元のコードがその出力を持つことは保証されていません。System.Diagnostics.Debugリリース ビルドでは、条件付きで呼び出されるため、出力はありません。

于 2011-06-11T13:37:19.743 に答える