Hi Leutz,
ich hab ein kleines Problem.
public class meinObject
{
public int zahl1;
public int zahl2;
}
public class meineAusführendeKlasse
{
public void TuWas()
{
int i1 = 1;
int i2 = 2;
meinObject tmpObject = new meinObject();
tmpObject.zahl1 = 3;
tmpObject.zahl2 = 154;
string tmpString = "(i1*tmpObject.zahl1)-tmpObject.zahl2";
}
}
Fragt mich jetzt bitte nicht warum man solche häßlichen Sachen macht, der String kommt ursprünglich aus ner Datenbank und wird mir da in so einer Form hinterlegt.
Gibt es für mich eine Möglichkeit nur eine Zeile c#-Code zu kompilieren und dann in der aktuellen Methode aufzurufen (zwecks des entsprechenden scopes)?!
Andere Lösungvorschläge?
THX für eure Hilfe.
Mfg
slig
Wir Arbeiten eigendlich nicht wir nehmen nur das geld
Erstmal Danke für die Antwort, aber dieses Beispiel hatte ich schon gefunden.
Nur brauch ich ja keine neue Assembly oder Klasse sondern lediglich diesen (verdammten) String in ner ausführbare Variante...
Zumal es mir auch nix bringen dürfte, nen neues Objekt zur Laufzeit generieren und erstellen zu lassen, da ich dann erst recht nicht mehr auf die im String benannten Objekte zugreifen kann, oder?!
Auch das durchparsen des Strings bringt mir nix, da ich, selbst wenn ich die Variablennamen der Objekte kenne leider immer noch nicht drauf zugreifen kann.
Ich such schon seit längerem nach einer Variante der $$variable wie es sie in PHP gibt, hab aber bisher nix gefunden.
Danke für eure Hilfe.
Mfg
slig
Hallo slig,
was du willst geht nicht.
herbivore
@slig:
und warum soll es nicht gehen den string zu parsen??
wenn in der Datenbank etwas steht wie: string a = "abc";.
dann könntest du einfach alles zwischen den "" auslesen
Wir Arbeiten eigendlich nicht wir nehmen nur das geld
Hallo S.H.-Teichhof,
parsen kann man den String natürlich, aber ausführen nicht.
Man kann nur in sich abgeschlossenen Code zur Laufzeit übersetzen und ausführen, aber man kann nicht Code (in einem String) im Kontext des gerade ausgeführen Codes übersetzen.
herbivore
@ZIMD: IN Scriptsprachen wie PHP und JavaScript gibt es die Methode/Befehl eval, der es zulässt, Text als Programmcode auszuführen. In C, C#, Java usw. geht das meines Wissens nicht.
Schau Dir doch mal etwas wie die AderTemplateEngine an.
Und es geht doch 😉 :
using System;
namespace StringParse
{
public class StringParseBaseClass
{
public StringParseBaseClass()
{
}
public virtual object ParseString()
{
return null;
}
}
public class DynamicClassCreator
{
public DynamicClassCreator()
{
}
public object ParseString(string stringToParse)
{
StringParseBaseClass testParser = new StringParseBaseClass();
Microsoft.CSharp.CSharpCodeProvider cp = new Microsoft.CSharp.CSharpCodeProvider();
System.CodeDom.Compiler.ICodeCompiler ic = cp.CreateCompiler();
System.CodeDom.Compiler.CompilerParameters cpar = new System.CodeDom.Compiler.CompilerParameters();
cpar.GenerateInMemory = true;
cpar.GenerateExecutable = false;
cpar.ReferencedAssemblies.Add("system.dll");
cpar.ReferencedAssemblies.Add("ConsoleApplication1.exe");
string src =
@"using System;
public class MeinObjekt1
{
public MeinObjekt1()
{
}
public int meinInt1 = 2;
public int meinInt2 = 5;
}
public class MeinObjekt2
{
public MeinObjekt2()
{
}
public int meinInt1 = 3;
public int meinInt2 = 4;
}
class MeinStringParser : StringParse.StringParseBaseClass
{
private MeinObjekt1 myObject1 = new MeinObjekt1();
private MeinObjekt2 myObject2 = new MeinObjekt2();
public MeinStringParser()
{
}
public override object ParseString()
{
return " + stringToParse + @";
}
}";
System.CodeDom.Compiler.CompilerResults cr = ic.CompileAssemblyFromSource(cpar,src);
foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors)
{
Console.WriteLine(ce.ErrorText);
}
if (cr.Errors.Count == 0 && cr.CompiledAssembly != null)
{
Type ObjType = cr.CompiledAssembly.GetType("MeinStringParser");
try
{
if (ObjType != null)
{
testParser = (StringParseBaseClass)Activator.CreateInstance(ObjType);
return testParser.ParseString();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
return null;
}
}
class Class1
{
[STAThread]
static void Main(string[] args)
{
string stringToParse =
"string.Format(\"Das Ergebnis ist: {0}.\", ((int) (((myObject1.meinInt1+myObject1.meinInt2)-myObject2.meinInt1)*myObject2.meinInt2)).ToString())";
// Berechnung von ((2+5)-3)*4 ...
DynamicClassCreator dynClass = new DynamicClassCreator();
Console.WriteLine((string) dynClass.ParseString(stringToParse));
Console.ReadLine();
}
}
}
Ist zwar super häßlich und sehr unflexibel, macht aber das, was es soll...
Mfg
slig
[edit]
Und ja - ich weiß, dass parsen eigentlich was anderes ist ... 🤔
[/edit]
Hi slig,
hast du es schon mal mit IronPython ironpython.orgprobiert?
Das ist ein Pythoninterpreter, der in C# eingebunden ist, und mit dem man dann auf aktuelle Objekte zugreifen kann.
Oder reicht dir deine Lösung?
Detlef
hm, sicher das du dann auch keine probleme bekommst wenn du nen zweiten string compilieren willst?
immerhin erstellst du ja im hintergrund quasie neuen il-code der dann in den aktuellen app-domain geladen wird, oder nicht?
und wenn du das dann nochmal aufrufst... was passiert dann?