用CodeDom、Reflection做一个简易计算器

 

将代码粘贴到一个VB文件即可运行。我这里只是给出一种思路,按这种思路,可以做出一个强劲的计算器,也可以做出一个代码测试器或者是练习器。

 

Option Strict Off

Imports System.IO

Imports System.CodeDom.Compiler

Imports System.Reflection

 

Namespace LzmTW.Test

    Public Class frmCal

        Inherits System.Windows.Forms.Form

 

        Private Code As New CodeBuilder

        Private myMode As Mode

 

#Region " Windows 窗体设计器生成的代码 "

 

        Public Sub New()

            MyBase.New()

 

            '该调用是 Windows 窗体设计器所必需的。

            InitializeComponent()

 

            ' InitializeComponent() 调用之后添加任何初始化

 

        End Sub

 

        '窗体重写 dispose 以清理组件列表。

        Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

            If disposing Then

                If Not (components Is Nothing) Then

                    components.Dispose()

                End If

            End If

            MyBase.Dispose(disposing)

        End Sub

 

        'Windows 窗体设计器所必需的

        Private components As System.ComponentModel.IContainer

 

        '注意: 以下过程是 Windows 窗体设计器所必需的

        '可以使用 Windows 窗体设计器修改此过程。

        '不要使用代码编辑器修改它。

        Friend WithEvents tbCode As System.Windows.Forms.TextBox

        Friend WithEvents tbResult As System.Windows.Forms.TextBox

        Friend WithEvents btnCal As System.Windows.Forms.Button

        Friend WithEvents tbReturnPara As System.Windows.Forms.TextBox

        Friend WithEvents Label1 As System.Windows.Forms.Label

        Friend WithEvents Label2 As System.Windows.Forms.Label

        Friend WithEvents tbSub As System.Windows.Forms.TextBox

        Friend WithEvents Label3 As System.Windows.Forms.Label

        Friend WithEvents Label4 As System.Windows.Forms.Label

        Friend WithEvents Button1 As System.Windows.Forms.Button

        Private Sub InitializeComponent()

            Me.tbCode = New System.Windows.Forms.TextBox

            Me.tbResult = New System.Windows.Forms.TextBox

            Me.btnCal = New System.Windows.Forms.Button

            Me.tbReturnPara = New System.Windows.Forms.TextBox

            Me.Label1 = New System.Windows.Forms.Label

            Me.Label2 = New System.Windows.Forms.Label

            Me.tbSub = New System.Windows.Forms.TextBox

            Me.Label3 = New System.Windows.Forms.Label

            Me.Label4 = New System.Windows.Forms.Label

            Me.Button1 = New System.Windows.Forms.Button

            Me.SuspendLayout()

            '

            'tbCode

            '

            Me.tbCode.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _

                        Or System.Windows.Forms.AnchorStyles.Left) _

                        Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)

            Me.tbCode.Location = New System.Drawing.Point(8, 32)

            Me.tbCode.Multiline = True

            Me.tbCode.Name = "tbCode"

            Me.tbCode.ScrollBars = System.Windows.Forms.ScrollBars.Both

            Me.tbCode.Size = New System.Drawing.Size(584, 72)

            Me.tbCode.TabIndex = 0

            Me.tbCode.Text = "'给定半径,求周长和面积" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "Dim M(3)" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "M(0)=20" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "M(1)=M(0)*Math.PI*2" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "M(2)=Math.PI*Math.Pow(M(0),2)" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "D" & _

            "im Result" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "Result=""半径:"" + M(0).Tostring +vbcrlf+""周长:"" + M(1).ToString+vbcrlf +""" & _

            ":"" +M(2).Tostring" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "        " & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "        " & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "'打开Excel" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "Dim oExcel As ExcelObj" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "oExcel" & _

            ".Open" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "oExcel.GetData(Result)"

            '

            'tbResult

            '

            Me.tbResult.Anchor = CType(((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left) _

                        Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)

            Me.tbResult.Location = New System.Drawing.Point(8, 360)

            Me.tbResult.Multiline = True

            Me.tbResult.Name = "tbResult"

            Me.tbResult.ScrollBars = System.Windows.Forms.ScrollBars.Both

            Me.tbResult.Size = New System.Drawing.Size(584, 64)

            Me.tbResult.TabIndex = 1

            Me.tbResult.Text = ""

            '

            'btnCal

            '

            Me.btnCal.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)

            Me.btnCal.Location = New System.Drawing.Point(448, 320)

            Me.btnCal.Name = "btnCal"

            Me.btnCal.Size = New System.Drawing.Size(120, 32)

            Me.btnCal.TabIndex = 2

            Me.btnCal.Text = "计算(&C)"

            '

            'tbReturnPara

            '

            Me.tbReturnPara.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)

            Me.tbReturnPara.Location = New System.Drawing.Point(104, 112)

            Me.tbReturnPara.Name = "tbReturnPara"

            Me.tbReturnPara.Size = New System.Drawing.Size(152, 21)

            Me.tbReturnPara.TabIndex = 3

            Me.tbReturnPara.Text = "Result"

            '

            'Label1

            '

            Me.Label1.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)

            Me.Label1.Location = New System.Drawing.Point(8, 112)

            Me.Label1.Name = "Label1"

            Me.Label1.Size = New System.Drawing.Size(72, 16)

            Me.Label1.TabIndex = 4

            Me.Label1.Text = "返回值参数"

            '

            'Label2

            '

            Me.Label2.Location = New System.Drawing.Point(8, 8)

            Me.Label2.Name = "Label2"

            Me.Label2.Size = New System.Drawing.Size(128, 16)

            Me.Label2.TabIndex = 5

            Me.Label2.Text = "主程序:"

            '

            'tbSub

            '

            Me.tbSub.Anchor = CType(((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left) _

                        Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)

            Me.tbSub.Location = New System.Drawing.Point(8, 176)

            Me.tbSub.Multiline = True

            Me.tbSub.Name = "tbSub"

            Me.tbSub.ScrollBars = System.Windows.Forms.ScrollBars.Both

            Me.tbSub.Size = New System.Drawing.Size(584, 136)

            Me.tbSub.TabIndex = 6

            Me.tbSub.Text = "Class ExcelObj" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "   Private shared obj,Wb,Ws" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "   Public Shared Sub Open" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "       ob" & _

            "j=CreateObject(""Excel.Application"")" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "       obj.Visible = True" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "   End Sub" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "   P" & _

            "ublic Shared Sub GetData(Value)" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "       If Wb Is Nothing Then" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "          Wb=obj." & _

            "WorkBooks.Add " & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "          Ws=Wb.WorkSheets.Add" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "       End If" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "       Ws.Cells(1" & _

            ",1)=Value" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "   End Sub" & Microsoft.VisualBasic.ChrW(13) & Microsoft.VisualBasic.ChrW(10) & "End Class"

            '

            'Label3

            '

            Me.Label3.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)

            Me.Label3.Location = New System.Drawing.Point(8, 152)

            Me.Label3.Name = "Label3"

            Me.Label3.Size = New System.Drawing.Size(128, 16)

            Me.Label3.TabIndex = 7

            Me.Label3.Text = "函数:"

            '

            'Label4

            '

            Me.Label4.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)

            Me.Label4.Location = New System.Drawing.Point(8, 336)

            Me.Label4.Name = "Label4"

            Me.Label4.Size = New System.Drawing.Size(128, 16)

            Me.Label4.TabIndex = 8

            Me.Label4.Text = "结果:"

            '

            'Button1

            '

            Me.Button1.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)

            Me.Button1.Location = New System.Drawing.Point(240, 320)

            Me.Button1.Name = "Button1"

            Me.Button1.Size = New System.Drawing.Size(120, 32)

            Me.Button1.TabIndex = 9

            Me.Button1.Text = "查看代码"

            '

            'frmCal

            '

            Me.AutoScaleBaseSize = New System.Drawing.Size(6, 14)

            Me.ClientSize = New System.Drawing.Size(600, 429)

            Me.Controls.Add(Me.Button1)

            Me.Controls.Add(Me.Label4)

            Me.Controls.Add(Me.Label3)

            Me.Controls.Add(Me.tbSub)

            Me.Controls.Add(Me.Label2)

            Me.Controls.Add(Me.Label1)

            Me.Controls.Add(Me.tbReturnPara)

            Me.Controls.Add(Me.btnCal)

            Me.Controls.Add(Me.tbResult)

            Me.Controls.Add(Me.tbCode)

            Me.Name = "frmCal"

            Me.Text = "简易代码计算器"

            Me.ResumeLayout(False)

 

        End Sub

 

#End Region

 

        Private Sub btnCal_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCal.Click

            Code.Clear()

            Dim i As Int16

            For i = 0 To tbCode.Lines.Length - 1

                Code.AppendCode(2, tbCode.Lines(i))

            Next

            Code.AppendCode(2, "Return " & Me.tbReturnPara.Text)

            Code.AppendCode(1, "End Function")

            Code.AppendCode()

            For i = 0 To tbSub.Lines.Length - 1

                Code.AppendCode(2, tbSub.Lines(i))

            Next

            myMode = New Mode

            myMode.GetMode(Code.ToString)

            ' MsgBox(myMode.CodeString)

            Me.tbResult.Text = ""

            Me.tbResult.Text = myMode.CalResult

        End Sub

 

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

            If Not myMode Is Nothing Then

                Me.tbResult.Text = ""

                Me.tbResult.Text = myMode.CodeString

            End If

        End Sub

    End Class

    Public Class Mode

        Private Comp As ICodeCompiler = New VBCodeProvider().CreateCompiler

        Private cp As CompilerParameters = New CompilerParameters

        Private _Compiled As Object = Nothing

        Private mi As MethodInfo

        Private MyCode As CodeBuilder

        Public ReadOnly Property CodeString() As String

            Get

                Return MyCode.ToString

            End Get

        End Property 'CodeString

        Sub New()

        End Sub

        Sub GetMode(ByVal ModeString As String)

            MyCode = New CodeBuilder

            With MyCode

                .AppendCode("Imports System")

                .AppendCode("Imports System.Data")

                .AppendCode("Imports System.Math")

                .AppendCode("Imports Microsoft.VisualBasic")

                .AppendCode()

                .AppendCode("Public Class DealMode")

                .AppendCode("   Public Function GetM()")

                .AppendCode(ModeString)

                ' .AppendCode("   End Function")

                .AppendCode("End Class")

            End With

        End Sub 'GetMode

        Public Function CalResult() As Object

            cp.ReferencedAssemblies.Add("System.dll")

            cp.ReferencedAssemblies.Add("System.Data.dll")

            cp.ReferencedAssemblies.Add("System.Xml.dll")

            cp.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll")

            cp.GenerateExecutable = False

            cp.GenerateInMemory = True

            'dim CodeBuilding as

            Dim code As String

            code = MyCode.ToString

 

            Dim cr As CompilerResults = Comp.CompileAssemblyFromSource(cp, code)

            Debug.Write(code.ToString)

            If (cr.Errors.HasErrors) Then

 

                Dim ErrorMessage As String

 

                ErrorMessage = "编译错误:" & vbCrLf

                Dim Err As CompilerError

                For Each Err In cr.Errors

                    ErrorMessage = ErrorMessage & Err.ErrorText & vbCrLf

                Next

                Debug.WriteLine(ErrorMessage)

#If DEBUG Then

            Stop

#Else

                Throw New Exception("编译错误: " + ErrorMessage)

#End If

            End If

 

            Dim a As System.Reflection.Assembly = cr.CompiledAssembly

            _Compiled = a.CreateInstance("DealMode")

            mi = _Compiled.GetType().GetMethod("GetM")

            Return mi.Invoke(_Compiled, Nothing)

        End Function

 

    End Class 'Mode

    Public Class CodeBuilder

        Private _StringBuilder As System.Text.StringBuilder

        Private Const CodeFormat As String = "{0}{1}" & ControlChars.CrLf

        Sub New()

            _StringBuilder = New System.Text.StringBuilder

        End Sub

        Public Overloads Sub AppendCode()

            _StringBuilder.AppendFormat(CodeFormat, Space(0), Space(0))

        End Sub

        Public Overloads Sub AppendCode(ByVal CodeString As String)

            _StringBuilder.AppendFormat(CodeFormat, Space(0), CodeString)

        End Sub

        Public Overloads Sub AppendCode(ByVal CodeFloor As Integer, ByVal CodeString As String)

            _StringBuilder.AppendFormat(CodeFormat, Space(CodeFloor * 4), CodeString)

        End Sub

        Public Sub AppendFromFile(ByVal FileName As String)

            If Not System.IO.File.Exists(FileName) Then

                MsgBox(FileName & "不存在.")

                Exit Sub

            End If

            Dim tmpStr As String

            Dim fs As System.IO.FileStream

            fs = New System.IO.FileStream(FileName, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)

            Dim Reader As New System.IO.StreamReader(fs, System.Text.Encoding.Default)

            tmpStr = Reader.ReadToEnd

            Reader.Close()

            fs.Close()

            _StringBuilder.Append(tmpStr)

        End Sub

        Public Overrides Function ToString() As String

            Return _StringBuilder.ToString

        End Function

        Public Sub Clear()

            If _StringBuilder.Length > 0 Then _StringBuilder.Remove(0, _StringBuilder.Length - 1)

        End Sub

    End Class 'CodeBuilder

End Namespace

 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值