VB.NET中的模块变量何时实例化? [英] When are a module's variables in VB.NET instantiated?
问题描述
<$ c $在程序的生命周期中,模块中的变量将被初始化c)Module Helper
Friend m_Settings As New UserSettings()
Sub Foo()
'...
End Sub
Sub Bar()
'...
End Sub
End Module
公共类UserSettings
公共类UserName As String
Public Property PrefServer As Integer
Public Sub New()
'...
End Sub
Public Sub LoadSettings()
'...
End Sub
End Class
何时 m_Settings
被初始化?我可以在 UserSettings
的构造函数中设置一个断点,然后查看调用堆栈,但是我在其中看到了外部代码,但这并没有告诉我很多。
CLR没有直接支持VB.NET模块,它需要所有方法和变量都是类型的一部分。所以VB.NET编译器实际上在后台生成了一个类。您在模块中编写的所有功能都成为该类的静态方法。您在模块中声明的所有变量都将成为该类的静态字段。
在您的模块中初始化的任何变量都会导致生成静态构造函数。初始化代码被移入此构造函数中。
现在,CLR规则适用:只要抖动触及此类的任何成员,CLR运行静态构造函数。然后初始化所有的模块变量。这也是为什么你在调用堆栈上看到[外部代码]的原因,调用是在CLR内部产生的。
这很少见,静态构造函数保证在CLR中是非常强大的。关于唯一棘手的事情是一个变量初始化器,它会导致引发异常。那是胆量开始显现的时候。堆栈跟踪相当神秘,因为它显示了源代码中不存在的代码。抛出的实际异常是TypeInitializationException,由于您没有编写任何类型,所以非常神秘,您需要查看它的InnerException以找到真正的原因。
I was wondering where in the lifetime of the program a variable that is in a module would be initialized as in this example:
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
When would m_Settings
be initialized? I can set a break point at the constructor for UserSettings
and look at the call stack, but I see "External Code" in there but that doesn't tell me a lot.
The CLR has no direct support for VB.NET modules, it requires all methods and variables to be part of a type. So the VB.NET compiler actually generates a class under the hood. All of the functions you wrote in the module become static methods of that class. All of the variables you declared in the module become static fields of the class.
Any variables that are initialized in your module causes a static constructor to be generated. And the initialization code is moved into this constructor.
Now CLR rules apply: a soon as the jitter touches any of the members of this class, the CLR runs the static constructor. Which then initializes all of the module variables. Which is also why you see [external code] on the call stack, the call originated inside the CLR.
It is rare to have problems with this, the static constructor guarantee in the CLR is a very strong one. About the only tricky mishap is a variable initializer that causes an exception to be thrown. That's when the guts start showing. The stack trace is pretty mystifying since it shows code that doesn't exist in your source code. The actual exception thrown is a TypeInitializationException, very mystifying since you didn't write any type, you need to look at its InnerException to find the real reason.
这篇关于VB.NET中的模块变量何时实例化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!