我已经在这篇文章中找到了这个问题的答案:https://stackoverflow.com/a/14711110/1764912
但是我的下一个查询是,当我尝试在这个动态代码中声明一个DataTable或MsgBox时,它给我一个错误,"Type'DataTable'未定义"和"Type'MsgBox'未定义"是.如果我使用动态代码中的第一行添加导入:
Imports System.Data
Run Code Online (Sandbox Code Playgroud)
要么
Imports System.Data.DataTable
Run Code Online (Sandbox Code Playgroud)
或者如果我在GenerateScript()函数中使用以下任何代码(请参阅/sf/answers/1029777731/以获取GenerateScript()函数)
Dim importDataNameSpace As String = GetType(DataTable).Namespace
Dim codeArray() As String = New String() {"Imports " & importDataNameSpace & Environment.NewLine & code}
Run Code Online (Sandbox Code Playgroud)
或者如果我使用
Dim codeArray() As String = New String() {"Imports System.Data" & Environment.NewLine & code}
Run Code Online (Sandbox Code Playgroud)
要么
Dim codeArray() As String = New String() {"Imports System.Data.DataTable" & Environment.NewLine & code}
Run Code Online (Sandbox Code Playgroud)
在上述所有情况下,它都会给我一个错误"System.Data不包含任何公共成员或找不到".
除非您首先引用库,否则导入名称空间不会对您有任何帮助.如果未引用库,则您导入的命名空间实际上将为空.
正如其他人在上面的评论中提到的那样,仅仅因为您System.Data.dll在项目中引用了库,这并不意味着它也会被您动态编译的程序集引用.每个程序集都需要直接引用它需要的所有程序集.动态编译的程序集也不例外.
通过该CompilerParameters.ReferencedAssemblies.Add方法将引用添加到动态程序集中.您可以在我对您链接的问题的回答中看到一个示例.在该示例中,我将动态程序集引用返回到主程序集,以便它可以使用该IScript接口.但是,您可以根据需要添加任意数量的引用.要添加引用System.Data.dll,您可以这样做:
Public Function GenerateScript(code As String) As IScript
Using provider As New VBCodeProvider()
Dim parameters As New CompilerParameters()
parameters.GenerateInMemory = True
parameters.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location)
parameters.ReferencedAssemblies.Add("System.Data.dll")
parameters.ReferencedAssemblies.Add("System.Xml.dll")
Dim interfaceNamespace As String = GetType(IScript).Namespace
Dim codeArray() As String = New String() {"Imports " & interfaceNamespace & Environment.NewLine & code}
Dim results As CompilerResults = provider.CompileAssemblyFromSource(parameters, codeArray)
If results.Errors.HasErrors Then
Throw New Exception("Failed to compile script")
Else
Return CType(results.CompiledAssembly.CreateInstance("Script"), IScript)
End If
End Using
End Function
Run Code Online (Sandbox Code Playgroud)
由于System.Data.dll程序集在GAC中,因此您无需指定完整路径.另请注意,为了使用DataTable,您还需要添加引用System.Xml.dll.一旦运行代码,就会发现它.
因此,如果您定义了上述方法,并且您定义了以下接口:
Public Interface IScript
Function DoWork() As String
End Interface
Run Code Online (Sandbox Code Playgroud)
然后,你可以像这样调用它:
Dim builder As New StringBuilder()
builder.AppendLine("Public Class Script")
builder.AppendLine(" Implements IScript")
builder.AppendLine(" Public Function DoWork() As String Implements IScript.DoWork")
builder.AppendLine(" Dim table As New System.Data.DataTable()")
builder.AppendLine(" table.TableName = ""Hello World""")
builder.AppendLine(" Return table.TableName")
builder.AppendLine(" End Function")
builder.AppendLine("End Class")
Dim script As IScript = GenerateScript(builder.ToString())
Console.WriteLine(script.DoWork()) ' Outputs "Hello World"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7326 次 |
| 最近记录: |