Laden...

Formeleditor

Erstellt von dr4g0n76 vor 17 Jahren Letzter Beitrag vor 14 Jahren 18.885 Views
dr4g0n76 Themenstarter:in
2.921 Beiträge seit 2005
vor 17 Jahren
Formeleditor

Oft wünscht man sich einen Formel-Editor. Da ich gerade einen gebraucht habe und dachte, wie stellt man das auf die schnelle an, kam ich auf die Idee reflection zu benutzen.

Zuerst habe ich im Netz nachgesehen und kam auf JScript, dass die Methode Eval benutzt. Diesen Code habe ich dann auch im Projekt belassen.

Aber ich wollte dann eigentlich doch etwas komfortableres haben, das ausbaubarer ist als JScript.

Also habe ich mit C# und dem Compiler eine eigene "Eval"-Funktionalität kreiert. Die übrigens sehr gut funktioniert.

Im Constructor werden die Compiler-Parameter initialisiert und Referenzen auf die benötigten DLLs eingestellt:


        public CReflectiveEvaluator()
        {
            m_CSharpCodeProvider = new CSharpCodeProvider();
            this.m_ICodeCompiler = m_CSharpCodeProvider.CreateCompiler();
            m_CompilerParameters = new CompilerParameters();
            m_CompilerParameters.GenerateInMemory = true;
            m_CompilerParameters.GenerateExecutable = false;
            m_CompilerParameters.ReferencedAssemblies.Add("system.dll");
            m_CompilerParameters.ReferencedAssemblies.Add("mscorlib.dll");
        }

und in eval wird der Code ausgeführt:


        public object Eval(string _sFormula)
        {
            string sSource = this.m_sFormulaTemplateClass.Replace("{1}",_sFormula);
            sSource = sSource.Replace("{0}",CreateVariablesDeclarationsInstructions());
            System.CodeDom.Compiler.CompilerResults cr = m_ICodeCompiler.CompileAssemblyFromSource(this.m_CompilerParameters, sSource);

            Type tMathEval = cr.CompiledAssembly.GetType("CMathEval");
            object oMathEval = Activator.CreateInstance(tMathEval);
            object o = oMathEval.GetType().GetMethod("Eval").Invoke(oMathEval, null);
            
            return o;
        }

Hier kommt noch ein kleiner Trick vor:

Der Konstruktor von der Eval-Klasse sieht so aus:


public object Eval()
{
    {0}
    object o = null;
    o={1};
    return o;
}

Zur Laufzeit werden jetzt die Variablen in {0} geschrieben (mittels String.Replace)
und in {1} wird genau auf die gleiche Weise, die Formel eingefügt.

Wenn jetzt jemand in den Formeleditor z.B. die Variable

a = 5;

und die Formel 4*a eingibt,

dann wird daraus:


public object Eval()
{
    double a = 5;
    object o = null;
    o=4*a;
    return o;
}

Es ist kaum zu glauben, aber das ist alles was benötigt wird, um den Code zu erzeugen und zur Laufzeit auszuführen.

Das Ergebnis wird dann per Invoke ermittelt in die Ergebnis-Textbox eingefügt.

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

J
3.331 Beiträge seit 2006
vor 17 Jahren

Hallo,

bitte korrigiere dringend Titel und Schreibfehler: Es geht ja nicht um Formular, sondern um Formel oder Formula. Danke! Jürgen

PS. Ich wurde sehr verwirrt und habe erst am Ende das eigentliche Thema erkannt.

/Edit: Danke schön!

dr4g0n76 Themenstarter:in
2.921 Beiträge seit 2005
vor 17 Jahren

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

D
481 Beiträge seit 2005
vor 17 Jahren

Sieht sehr nett aus 👍 Was noch eine gute Funktion wäre, und zwar das ganze auch für Graphen realisieren.

Dexter

Programmierer sind Maschinen die Koffein in Quellcode umsetzen.

dr4g0n76 Themenstarter:in
2.921 Beiträge seit 2005
vor 17 Jahren

Der Funktionsplotter ist inzwischen auch schon geschrieben, aber noch nicht getestet.
Den werde ich vielleicht nächste Woche auch noch hier posten.

Der Formeleditor hat ein Update erfahren. Es kann jetzt auch gespeichert und geladen werden.

Den Funktionsplotter gibts jetzt auch.

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

F
85 Beiträge seit 2007
vor 16 Jahren
Warnung in VS2008

Hi dr4g0n76,

erstmal Glückwunsch zu diesem tollen Programm. Funktioniert echt Super.

Ich würde gerne deinen Code in einem meiner Programme benutzen. (Ich hoffe dass geht in Ordnung?!?!?)

Soweit funktioniert alles super außer dass der Kompiler Warnungen (siehe unten) ausgibt. Hängt das an VS2008? Oder Kommen die Warnungen immer? Kann man dass beheben ?

Gruß


Warning	1	'System.CodeDom.Compiler.CodeDomProvider.CreateCompiler()' is obsolete: 'Callers should not use the ICodeCompiler interface and should instead use the methods directly on the CodeDomProvider class. Those inheriting from CodeDomProvider must still implement this interface, and should exclude this warning or also obsolete this method.'	C:\Dokumente und Einstellungen\Seebach\Eigene Dateien\Visual Studio 2008\Projects\Werteeingabe2\werte_control\math\CReflectiveEvaluator.cs	20	36	werte_control
1.665 Beiträge seit 2006
vor 16 Jahren

Scheint so, dass 'System.CodeDom.Compiler.CodeDomProvider.CreateCompiler()' in .NET 3.5 obsolet ist, was es wohl dann in <3.5 nicht war.

M
2 Beiträge seit 2006
vor 14 Jahren

der Rechner ist super, jedoch hat er durch die Reflection Probleme mit , Zahlen da er . statt , erwartet. Bsp: -> 5/0,5 funktioniert nicht. richtig wäre 5/0.5.

Und ein großes Sicherheitsrisiko durch Reflection ist auch das man schwer prüfen kann, was der User dort eingibt.

BSP: -> Bei der Eingabe System.IO.File.Create("C:\abc.txt") wird ne datei angelegt.
Damit ist jedem Tür und Tor zum System geöffnet.

Natürlich kann man in dem Frontend so Eingaben filtern und verhindern.
Ansonsten finde ich den Calculator super.