Есть ли стандартный способ работы загрузчиков классов .NET? - PullRequest
3 голосов
/ 11 июня 2011

Есть ли стандартный способ работы загрузчиков классов .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

Ответы [ 2 ]

5 голосов
/ 11 июня 2011

Да, порядок вызова статических и конструкторов экземпляров является частью спецификации языка.Все соответствующие компиляторы должны выдавать один и тот же IL для этой программы.

4 голосов
/ 11 июня 2011

Поскольку вы используете конструкторы, а не встроенную инициализацию, компилятор 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 условно вызывается.

...