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 回答