我试图将VB源文件加载到内存中。但是,VB文件假定它与之关联的Project具有一些全局"导入的命名空间"在项目层面定义。此VB功能允许单个文件在每个文件中省略Imports语句(在C#中使用)。
Dim sourceCode As String = ""
'sourceCode &= "Imports System.Data" & vbNewLine
sourceCode &= "Class Foo" & vbNewLine
sourceCode &= "Sub Print()" & vbNewLine
sourceCode &= "Dim dtbl As DataTable" & vbNewLine
sourceCode &= "System.Console.WriteLine(""Hello, world!"")" & vbNewLine
sourceCode &= "End Sub" & vbNewLine
sourceCode &= "End Class" & vbNewLine
Dim compiler As New Microsoft.VisualBasic.VBCodeProvider
Dim params As New Compiler.CompilerParameters
params.ReferencedAssemblies.Add("System.dll")
params.ReferencedAssemblies.Add("System.Data.dll")
params.ReferencedAssemblies.Add("System.Xml.dll")
params.GenerateInMemory = True
params.GenerateExecutable = False
Dim results As Compiler.CompilerResults = compiler.CompileAssemblyFromSource(params, sourceCode)
If results.Errors.Count > 0 Then
For Each compileError In results.Errors
Console.WriteLine(compileError.ToString)
Next
Return
End If
Dim assembly = results.CompiledAssembly
第2行被注释掉了。如果我取消注释并添加Imports语句,代码工作正常。如果我改变" Dim dtbl As DataTable"它也可以正常工作。 to" Dim dtbl As System.Data.DataTable"。
有没有一种方法可以将这个Imports语句提供给编译器或params,就好像它是一个全局项目级别的Imported Namespace?
而不是取消注释那行代码?我可以将这个Imports语句添加到我读入的每个文件的顶部。但是如果它已经存在,那么我得到一个错误,Imports语句是重复的。我可以做一些正则表达式检查,看看Imports语句是否已经存在,但我想尽可能地利用System.CodeDom框架。
答案 0 :(得分:1)
好的,没有答案:(我想框架不会做我想做的事。这是我使用Regex注入Imports语句的hacky解决方案。
sourceCode = AddImportsIfNeeded(sourceCode, "System.Data")
Private Function AddImportsIfNeeded(ByVal sourceCode As String, ByVal namespaceToImport As String) As String
If Not Regex.IsMatch(sourceCode, "^\s*Imports\s+" & Regex.Escape(namespaceToImport) & "\s*$", RegexOptions.Multiline) Then
Return "Imports " & namespaceToImport & vbNewLine & sourceCode
End If
Return sourceCode
End Function
请注意,如果文件包含Option语句(如Option Strict On),则不起作用。 Imports语句必须低于Option语句。
答案 1 :(得分:0)
您可以使用CompilerOptions
类的CompilerParameters
属性导入名称空间。将此行添加到您的示例中,编译器将不再生成编译器错误:
params.CompilerOptions = "/import:System.Data"