问题描述
我正在尝试将 VB 源文件加载到内存中.但是,VB 文件假定与其关联的项目具有在项目级别定义的一些全局导入的命名空间".此 VB 功能允许单个文件在每个文件上省略 Imports 语句(在 C# 中使用).
I'm trying to load a VB source file into memory. However, the VB file assumes that Project it is associated to has some global "Imported Namespaces" defined at the project level. This VB feature allows individual files to omit the Imports statement (Using in C#) on every single file.
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"更改为Dim dtbl As System.Data.DataTable",它也可以正常工作.
Line 2 is commented out. If I uncomment this and add the Imports statement the code works fine. It also works fine if I change "Dim dtbl As DataTable" to "Dim dtbl As System.Data.DataTable".
有没有办法将这个 Imports 语句提供给编译器或参数,而不是取消对那行代码的注释,就好像它是一个全局项目级别的导入命名空间一样?
Instead of uncommenting that line of code, is there a way to feed this Imports statement into the compiler or params as if it was a global project level Imported Namespace?
我可以将这个 Imports 语句添加到我读入的每个文件的顶部.但是如果它已经存在,那么我会收到一个错误,即 Imports 语句是重复的.我可以做一些正则表达式检查,看看 Imports 语句是否已经存在,但我想尽可能地利用 System.CodeDom 框架.
I could just add this Imports statement to the top of each file I read in. But if it is already there then I get an error that the Imports statement is duplicate. I could do some Regex checking to see if the Imports statement is already there, but I'd like to leverage the System.CodeDom framework as much as possible.
推荐答案
好的,没有答案 :( 我猜框架没有做我想做的事情.这是我使用正则表达式注入导入的 hacky 解决方案声明.
OK, no answers :( I guess the framework doesn't do what I'd like to do. Here is my hacky solution using Regex to inject the Imports statement.
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 语句之下.
Note that this won't work if the file contains Option statements (like Option Strict On). The Imports statements must go below the Option statements.
这篇关于如何将导入的命名空间提供给 CompileAssemblyFromSource的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!