Laden...

C#-Codestring während der Laufzeit ausführen

Erstellt von slig vor 18 Jahren Letzter Beitrag vor 18 Jahren 3.700 Views
slig Themenstarter:in
7 Beiträge seit 2005
vor 18 Jahren
C#-Codestring während der Laufzeit ausführen

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

1.549 Beiträge seit 2004
vor 18 Jahren

Wir Arbeiten eigendlich nicht wir nehmen nur das geld

slig Themenstarter:in
7 Beiträge seit 2005
vor 18 Jahren

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

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo slig,

was du willst geht nicht.

herbivore

1.549 Beiträge seit 2004
vor 18 Jahren

@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

49.485 Beiträge seit 2005
vor 18 Jahren

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

564 Beiträge seit 2005
vor 18 Jahren

In PHP geht das aber 😉

I
111 Beiträge seit 2006
vor 18 Jahren

@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.

F
10.010 Beiträge seit 2004
vor 18 Jahren

Schau Dir doch mal etwas wie die AderTemplateEngine an.

http://www.codeproject.com/csharp/adertemplateengine.asp

slig Themenstarter:in
7 Beiträge seit 2005
vor 18 Jahren

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]

D
95 Beiträge seit 2005
vor 18 Jahren

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

S
1.047 Beiträge seit 2005
vor 18 Jahren

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?