2

我正在尝试将 VB 源文件加载到内存中。但是,VB 文件假定与其关联的项目具有在项目级别定义的一些全局“导入命名空间”。此 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”更改为“Dim dtbl As System.Data.DataTable”,它也可以正常工作。

有没有办法将这个 Imports 语句提供给编译器或参数,而不是取消注释那行代码,就好像它是一个全局项目级别的 Imported Namespace?

我可以将这个 Imports 语句添加到我读入的每个文件的顶部。但如果它已经存在,那么我会收到 Imports 语句重复的错误。我可以做一些正则表达式检查以查看 Imports 语句是否已经存在,但我想尽可能地利用 System.CodeDom 框架。

4

2 回答 2

1

好的,没有答案:(我猜框架没有做我想做的事。这是我使用正则表达式注入 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 语句下方。

于 2012-11-01T03:55:27.497 回答
0

CompilerOptions您可以使用类的属性导入命名空间CompilerParameters。将此行添加到您的示例中,编译器将不再生成编译器错误:

params.CompilerOptions = "/import:System.Data"
于 2016-06-09T15:27:53.080 回答