none
Wo findet die Berechnung statt RRS feed

  • Frage

  • Hi Leute
    ich bin's wieder ma'. Folgendes:
    anhand folgendem Quellcode soll für eine beliebige mathematische Gleichung f(x)=y  
    y berechnet werden.

    Ich habe dazu eine Klasse anhand welcher aber auch keine Berechnungen ersichtlich sind. Ist vielleicht der Import der System.Math für die Berechnung zuständig? Wo genau wird denn dann y berechnet??

    Public Class Form1

        Private Sub Berechnung()
            ' Den Formelausdruck zuweisen: 

            Dim str As String = TextBox1.Text.ToUpper()

            ' Parameter X, Y, Z direkt in den Formelausdruck einbauen:

            str = str.Replace("X", TextBox2.Text).Replace("Y", TextBox3.Text).Replace("Z", TextBox4.Text)
            ' Start der Berechnung: Wo wird denn hier etwas berechnet??
            Try
                Dim res As Double = CCalculator.Calc(str) 'hier etwa?: 
                                'in der entsprechenden Klasse is' nix zu finden
                str = res.ToString()
                
                Label1.Text = str.Replace(",", ".")
            Catch ex As Exception
                Label1.Text = String.Empty
                MessageBox.Show(ex.Message)
            End Try
        End Sub

        ' Alle vier TextBoxen verwenden den folgenden gemeinsamen KeyPress-Eventhandler,
        ' ... er sorgt dafür, dass die Berechnung mittels Enter-Taste gestartet wird:
        Private Sub TextBox_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress,_  
    TextBox4.KeyPress, TextBox3.KeyPress, TextBox2.KeyPress

            If e.KeyChar = ChrW(Keys.Enter) Then
                Berechnung()
                e.Handled = True
            End If
        End Sub

        ' Beenden
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Me.Close()
        End Sub

        Public Sub New()

            ' Dieser Aufruf ist für den Windows Form-Designer erforderlich.
            InitializeComponent()

            ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.

            TextBox1.Text = "x*x+2*x*3":TextBox2.Text="":TextBox3.Text=""

      End Sub
    End Class

    Klasse:

    Imports System.CodeDom.Compiler
    Imports System.Reflection

    Public Class CCalculator
        Private Shared ass As Assembly
        Private Shared aClass As Type
        Private Shared aMethod As MethodInfo
        Private Shared obj As Object

        Public Shared Function Calc(expr As String) As Double
            If expr.Length = 0 Then Return 0.0
            ' Im Formelausdruck werden die Dezimalkommas durch Dezimalpunkte ersetzt:
            expr = expr.Replace(",", ".")
            ' Compilerparameter(definieren)
            Dim opt As New CompilerParameters(Nothing, String.Empty, False)
            opt.GenerateExecutable = False
            opt.GenerateInMemory = True

            ' VB-Quellcode zeilenweise zusammenbauen:
            Dim src As String = "Imports System.Math" & vbCrLf & _ 'wird dadurch etwa berechnet.Wie??
            "Public Class Calculate" & vbCrLf & _
                "Public Function Calc() As Double" & vbCrLf & _
                    "Return " & expr & vbCrLf & _
                "End Function" & vbCrLf & _
            "End Class" & vbCrLf

            ' Kompilieren:
            Dim res As CompilerResults = New VBCodeProvider().CompileAssemblyFromSource(opt, src)

            If res.Errors.Count > 0 Then
                Dim errors As String = String.Empty
                For Each cerr As CompilerError In res.Errors
                    errors = errors & cerr.ToString() & vbCrLf
                Next
                ass = Nothing
                expr = String.Empty
                Throw New ApplicationException(errors)
            End If
            ' vom Compiler erzeugte Assembly kann nun mittels Reflection-Mechanismus ausgewertet werden:        
            ass = res.CompiledAssembly
            'interne Klasse aus der Assembly herausziehen:
            aClass = ass.GetType("Calculate")
            ' interne Methode:  
            aMethod = aClass.GetMethod("Calc")
            ' Instanz der internen Klasse erzeugen:
            obj = Activator.CreateInstance(aClass)
            ' interne Methode aufrufen und das Ergebnis zurück liefern:
            Return Convert.ToDouble(aMethod.Invoke(obj, Nothing))
        End Function
    End Class


    • Bearbeitet tklustig Dienstag, 26. Juli 2016 19:27
    Dienstag, 26. Juli 2016 19:15

Antworten

Alle Antworten