Imports System.Reflection
Imports System.CodeDom
Imports System.CodeDom.Compiler
Public Class SourceComp
''//编译器接口
Private m_Compiler As ICodeCompiler
''//编译器参数
Private m_CompilerParameters As CompilerParameters
''//引用的程序集
Private m_RefAssemblies As String() = {"System.dll", "System.Data.dll"}
''//源代码
Private m_Source As String = ""
''//记录是否是默认的源代码
Private m_Is_Default As Boolean = True
''//记录编译状态
Private m_Compiled As Boolean = False
''//编译生成的程序集
Private m_Assembly As System.Reflection.Assembly
''//默认源代码生成的实例
Private m_tmpClass As Object
''//默认源代码生成的实例函数
Private m_MethodInfo As System.Reflection.MethodInfo
''//默认源代码函数的表达式参数
Private m_Expression As String
''//返回程序集
Public ReadOnly Property cpAssembly() As System.Reflection.Assembly
Get
Return Me.m_Assembly
End Get
End Property
Sub New()
''//获取VB编译器实例
Me.m_Compiler = New VBCodeProvider().CreateCompiler
''//初始编译器参数
Me.m_CompilerParameters = New CompilerParameters
With Me.m_CompilerParameters
.GenerateExecutable = False ''//False值指定编译为类集,True编译为可执行程序
.GenerateInMemory = False ''//只在内存中生成程序集,不输出到磁盘
''//添加默认的程序集
Me.Add_CompilerParameters()
End With
End Sub
''//添加要引用的程序集
Private Sub Add_CompilerParameters()
Me.m_CompilerParameters.ReferencedAssemblies.AddRange(Me.m_RefAssemblies)
End Sub
''//添加指定的引用程序集
Public Sub Add_CompilerParameters(ByVal RefAssemblies As String())
Me.m_RefAssemblies = RefAssemblies
Me.m_CompilerParameters.ReferencedAssemblies.Clear() ''//清除原有的程序集,重复引用编译会产生异常
Me.Add_CompilerParameters()
End Sub
''//生成默认的源代码
''//类名:tmpClass
''//函数名:GetExpressionValue ,参数:Expression ,参数类型:字符串
''//主要功能:返回表达式Expression的值 ,返回值类型:Object
Private Sub BuildDefaultSource()
Dim mCodeBuilder As CodeBuilder = New CodeBuilder
With mCodeBuilder
.AppendCode("Imports System")
.AppendCode("Imports System.Data")
.AppendCode("Imports System.Math")
.AppendCode("Imports Microsoft.VisualBasic")
.AppendCode()
.AppendCode("Public Class tmpClass")
.AppendCode(" Public Function GetExpressionValue() As Object")
.AppendCode(" Dim Result As Object")
.AppendCode(" Result={0}") ''这里传入表达式
.AppendCode(" Return Result")
.AppendCode(" End Function")
.AppendCode("End Class")
End With
Me.m_Source = mCodeBuilder.ToString
End Sub
''//指定源代码
Public Sub SetSource(ByVal Source As String)
Me.m_Source = Source
Me.m_Compiled = False
Me.m_Is_Default = False
End Sub
''//从指定文件中读取源代码
Public Sub GetSourceFormFile(ByVal SourceFileName As String)
Dim mCodeBuilder As CodeBuilder = New CodeBuilder
mCodeBuilder.AppendFromFile(SourceFileName)
Me.m_Source = mCodeBuilder.ToString
Me.m_Compiled = False
Me.m_Is_Default = False
End Sub
''//编译
Public Sub Complile()
If Me.m_Source = "" Then
Me.BuildDefaultSource()
End If
If Me.m_Is_Default Then
''传入参数
Me.m_Source = String.Format(Me.m_Source, Me.m_Expression)
End If
Dim mCompResult As CompilerResults = Me.m_Compiler.CompileAssemblyFromSource(Me.m_CompilerParameters, Me.m_Source)
''//错误提示
If (mCompResult.Errors.HasErrors) Then
Dim ErrorMessage As String
ErrorMessage = "编译错误:" & vbCrLf
Dim Err As CompilerError
For Each Err In mCompResult.Errors
ErrorMessage = ErrorMessage & Err.ErrorText & vbCrLf
Next
Throw New Exception("编译错误: " + ErrorMessage)
End If
Me.m_Assembly = mCompResult.CompiledAssembly
Me.m_Compiled = True
End Sub
''//如果是默认源代码,此函数取表达式的值;
''//如果自定义源代码,请参考本函数视实际自己写
Public Function GetExpressionValue(ByVal Expression As String) As Object
If Not Me.m_Is_Default Then
MsgBox("所用的代码不是默认代码,此函数无效")
Return Nothing
End If
''如果还没有编译则编译
If Not Me.m_Compiled Then
''//传入参数表达式作为代码
Me.m_Expression = Expression
Complile()
''//生成实例,注意类名区分大小写
Me.m_tmpClass = Me.m_Assembly.CreateInstance("tmpClass")
''//取函数,注意大小写
m_MethodInfo = Me.m_tmpClass.GetType().GetMethod("GetExpressionValue")
End If
当中要用到些反射的知识,反射的使用在NET中真是无处不在,使用反射没什么效率不效率的问题,毕竟现在的电脑配置并不是很低。适当使用反射,或者通过使用反射本身,会使自己加深对NET的理解。
机器语言,10100……