VB.NET中的模块变量何时实例化? [英] When are a module's variables in VB.NET instantiated?

查看:129
本文介绍了VB.NET中的模块变量何时实例化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 <$ 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆