Директивы препроцессора VB.NET
Почему не #IF Not DEBUG
работать так, как я ожидал бы в VB.NET?
#If DEBUG Then
Console.WriteLine("Debug")
#End If
#If Not DEBUG Then
Console.WriteLine("Not Debug")
#End If
#If DEBUG = False Then
Console.WriteLine("Not Debug")
#End If
' Outputs: Debug, Not Debug
Но, вручную установленный const делает:
#Const D = True
#If D Then
Console.WriteLine("D")
#End If
#If Not D Then
Console.WriteLine("Not D")
#End If
' Outputs: D
И, конечно же, C# имеет ожидаемое поведение:
#if DEBUG
Console.WriteLine("Debug");
#endif
#if !DEBUG
Console.WriteLine("Not Debug");
#endif
// Outputs: Debug
1 ответ
Оказывается, это не весь 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.
Мораль истории? #If Not
не очень хорошая идея для VB.NET.
И теперь, когда этот источник доступен, я могу убедиться, что он действительно установил его равным 1, как я ожидал:
if (options.IncludeDebugInformation) {
sb.Append("/D:DEBUG=1 ");
sb.Append("/debug+ ");
}