我继承了一个VB.NET项目,该项目使用模块来检查一些用户权限。
其中一个函数叫做UserLevel,它会调用硬件.dll文件来读取一些序列号。该函数如下所示:
Public Function UserLevel() As Integer
Dim status As Integer = userLevelWrapper.hardware.ReadInteger()
If status = 0 Then
If userLevelWrapper.readDaysLeft() > 0 Then
Return 2 'The user is a temporary user
Else
Return 0 'The user is invalid
End If
ElseIf Environment.UserName = "User1" OrElse _
Environment.UserName = "User2" Then
'There are more of these, and the user names are obviously not "User1" and "User2" because I've changed them for posting purposes.
Return 1 'The user is a developer
Else
Return 0 'The user is invalid
End If
End Function
出于某种原因,我无法在调试时进入此模块。我无法弄清楚它是如何配置的,所以我必须在我去的时候进行更改并检查结果。我只是想让模块告诉我的应用程序我是开发人员,所以我不间断地使用该应用程序。我已成功完成此操作,方法是将UserLevel函数更改为:
Public Function UserLevel() As Integer
Return 1 'I am a developer
'All other code remains the same, and is not commented.
End Function
因为我没有正确安装userLevelWrapper包,所以在实际执行代码时会出现FileNotFoundException。我假设在执行Dim status As Integer...
行时发生了这种情况,因此我将该行更改为
Dim status As Integer = 123456789 'userLevelWrapper.hardware.ReadInteger()
这显然会强制If
语句评估为false。当我运行它时,我仍然得到FileNotFoundException。
我发现该函数正在生成异常,因为存在在第5行调用.readDaysLeft()
的硬件.dll,即使它没有被执行。当我评论该行和.ReadInteger()
调用时,不会抛出任何异常。
我在这个案子中的问题是两部分:
1.当函数的第一行是Return 1
时,为什么不抛出异常,而我没有评论硬件调用?
2.为什么模块在没有执行代码时试图解析文件的位置?
尝试在编译时解析文件是有意义的,但为什么它只是在运行时通过解析它而只是在某些任意条件下生成自己的规则?
答案 0 :(得分:1)
这不是任意的。
当代码被注释掉时,它不会被编译成由JIT编译器转换为机器代码的IL代码。
如果不对其进行注释,那么代码的该分支是否编译为IL将成为编译器实现细节,您无法对其进行假设。也许它足够聪明,知道分支永远不会被执行......也许分析成本太高,所以它不会这样做。 JIT编译器可能会在函数级别将代码编译到机器级别,在这种情况下,它必须将整个函数编译为机器代码。那时它需要找到包含你调用和失败的函数的程序集。
如果您将状态更改为Constant
,编译器可能会识别出一个永远不会执行的分支,并将其优化为IL。