事实证明,并非VB.NET全部有问题,只有CodeDomProvider存在问题(ASP.NET和Snippet Compiler都使用该提供程序)。
给定一个简单的源文件:
Imports System
Public Module Module1
Sub Main()
#If DEBUG Then
Console.WriteLine("Debug!")
#End If
#If Not DEBUG Then
Console.WriteLine("Not Debug!")
#End If
End Sub
End Module
使用vbc.exe版本9.0.30729.1 (.NET FX 3.5)进行编译:
> vbc.exe default.vb /out:out.exe
> out.exe
Not Debug!
这很有道理...我没有定义 DEBUG,所以它显示“非调试版本!”。
> vbc.exe default.vb /out:out.exe /debug:full
> out.exe
Not Debug!
同时,使用CodeDomProvider:
Using p = CodeDomProvider.CreateProvider("VisualBasic")
Dim params As New CompilerParameters() With { _
.GenerateExecutable = True, _
.OutputAssembly = "out.exe" _
}
p.CompileAssemblyFromFile(params, "Default.vb")
End Using
> out.exe
Not Debug!
好的,再解释一下 - 那很有道理。我没有定义 DEBUG,所以显示“非调试”。但是,如果我包含调试符号呢?
Using p = CodeDomProvider.CreateProvider("VisualBasic")
Dim params As New CompilerParameters() With { _
.IncludeDebugInformation = True, _
.GenerateExecutable = True, _
.OutputAssembly = "C:\Users\brackett\Desktop\out.exe" _
}
p.CompileAssemblyFromFile(params, "Default.vb")
End Using
> out.exe
Debug!
Not Debug!
嗯...我没有定义DEBUG,但也许它为我定义了?但是如果它这样做了,它肯定将其定义为"1" - 因为我无法通过任何其他值来获取该行为。ASP.NET 使用 CodeDomProvider,必须以相同的方式进行定义。
看起来CodeDomProvider在VB.NET的愚蠢的伪逻辑运算符上出问题了。
故事的寓意?对于VB.NET来说,#If Not
不是一个好主意。
现在该源代码已经可用,我可以验证它实际上将其设置为1,就像我所预期的那样:
if (options.IncludeDebugInformation) {
sb.Append("/D:DEBUG=1 ");
sb.Append("/debug+ ");
}