myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Basistechnologien und allgemeine .NET-Klassen » [gelöst] Lambda Funktionen in einem Script bzw. zur Laufzeit kompilierten Code.
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

[gelöst] Lambda Funktionen in einem Script bzw. zur Laufzeit kompilierten Code.

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.885
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland


dr4g0n76 ist offline

[gelöst] Lambda Funktionen in einem Script bzw. zur Laufzeit kompilierten Code.

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Leute!

Ich hatte ja hier mal die Projekte  Funktionsplotter und  Formeleditor veröffentlicht.
Diese nutzen für die Funktionalität zur Laufzeit übersetzten Code.

Jetzt kam ich gestern auf die Idee das ganze von außen zu erweitern, in dem ich an einer Stelle einen Lambda-Ausdruck verwende, dieser ist Basis für ein Delegate
das an eine Klasse übergeben wird, die diesen Ausdruck auswertet bzw. ausführt.

Wenn ich keinen zur Laufzeit übersetzten Code benutze, funktioniert das ganze.
Wenn ich aber den oben beschriebenen Mechanismus benutze, behauptet der Compiler es würde eine ")" fehlen. Füge ich eine hinzu, verlangt er noch eine usw.

Jetzt meine Frage:

Ist es möglich, dass man etwas spezielles beachten muss, wenn man einen Lambda-Ausdruck auf die oben beschriebene Methode zur Laufzeit kompilieren möchte?

P.S.:

Falls das ganze nicht ganz klar ist, ich kann auch gerne den generierten Code und das Projekt dazu posten.

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von dr4g0n76 am 07.10.2016 12:56.

14.10.2009 11:10 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
JAck30lena JAck30lena ist männlich
myCSharp.de-Team

avatar-2653.jpg


Dabei seit: 01.10.2006
Beiträge: 11.397
Entwicklungsumgebung: Visual Studio 05/08/10 Prof.


JAck30lena ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

das musst du durch die Expression<T> klasse schleusen. diese hat dann eine Compile methode, welche dir dann irgendwie etwas IL code leifert oder so ähnlich. ich baue mir privat auch sowas für wpf und bindings, damit ich ein wenig mehr tricksen kann aber ich konnte ncoh nicht ausreichend zeit investieren um durchzusteigen.
14.10.2009 11:19 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.885
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

@JAck30lena:

Ok, das erklärt das Problem. ;-) Denn der generierte Code ist eine vollständige in C# generierte Klasse und lässt sich nämlich im Compiler ohne Probleme MIT Lambda-Ausdruck komplett übersetzen.

Aber auch wenn ich den Lambda-Ausdruck herauswerfe und das Projekt komplett zur Laufzeit kompilieren lasse, funktioniert es.

Dann werde ich wohl auch mal Zeit investieren müssen. Können wir uns ja gegenseitig helfen. ;-)
14.10.2009 11:56 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Peter Bucher Peter Bucher ist männlich
myCSharp.de-Poweruser/ Experte

avatar-4103.jpg


Dabei seit: 17.03.2005
Beiträge: 5.885
Entwicklungsumgebung: VS 2017 / VS Code
Herkunft: Zentralschweiz


Peter Bucher ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo dr4g0n76

Stichwort: Expression Tree, Artikel dazu:  [Artikel] Delegaten, anonyme Methoden, Lambda-Ausdrücke & Co.

Ein ExpressionTree bildet schlussendlich _nur_ eine Funktion ab, nicht mehr und nicht weniger.
Daher denke ich, das es für dich nicht geeignet ist, so wie du dein Szenario beschreibst.


Gruss Peter
14.10.2009 11:59 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.885
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Danke für den Tipp @ Peter Bucher,

hier ist ebenfalls etwas womit man einen Versuch starten könnte:

 Using Expressions for Fun and Profit

Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von dr4g0n76 am 14.10.2009 12:17.

14.10.2009 12:16 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
JAck30lena JAck30lena ist männlich
myCSharp.de-Team

avatar-2653.jpg


Dabei seit: 01.10.2006
Beiträge: 11.397
Entwicklungsumgebung: Visual Studio 05/08/10 Prof.


JAck30lena ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

hier habe ich noch etwas interessantes:
 http://www.ohloh.net/p/linq2codedom
14.10.2009 12:22 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dN!3L dN!3L ist männlich
myCSharp.de-Poweruser/ Experte

avatar-2985.png


Dabei seit: 13.08.2004
Beiträge: 2.891


dN!3L ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo dr4g0n76,

Zitat von dr4g0n76:
Falls das ganze nicht ganz klar ist...

Hm, so ganz hab ich's noch nicht... Willst du aus einer Zeichenkette (die einen Lambda-Ausdruck darstellt) zur Laufzeit auswerten und dann "ausführen"? Dann hilft dir vielleicht
 Expression<Func<T, T>> aus string erzeugen?

Gruß,
dN!3L
14.10.2009 12:32 Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.885
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

@dN!3L:

Untenstehende Klasse wird zur Laufzeit erzeugt als String und dann kompiliert.

C#-Code:
        using LambdaImageProcessing;
        using System.Drawing;

        public class LambdaScript
        {
            LambdaCommand command = new LambdaCommand();

            public LambdaScript()
            {
            }

            public void Test(Bitmap _bitmap)
            {
                command.Apply(_bitmap,
                    (Color c, int x, int y) => Color.FromArgb(c.R, c.G, c.B)  // <== hier
                );
            }
        }

An der fett markierten Zeile stört sich der Compiler zur Laufzeit, wenn ich die entsprechenden Befehle benutze und dann CompileFromSourceCode aufrufe.

Die Fehlermeldung die ich erhalte:

Zitat:
) erwartet.

Genau diesen String, nicht mehr und nicht weniger erhalte ich, eine ")" hinzuzufügen, kann ich so oft ich will der Fehler bleibt immer gleich.


Wird die Klasse aber genau so in das Projekt DIREKT eingebunden und NICHT zur Laufzeit generiert, kann Visual Studio das ganze ohne Probleme übersetzen und ausführen.
14.10.2009 13:57 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
spike24 spike24 ist männlich
myCSharp.de-Mitglied

Dabei seit: 01.02.2008
Beiträge: 443
Herkunft: Steiermark Österreich


spike24 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Kann sein dass ich da jetzt daneben liege, aber:
ich kompilere mit CodeDom zur Laufzeit code (string => dll)

und da musste ich dem CodeDom Compiler sagen das ich 3.5 haben will

vielleicht fehlt das da einfach auch.
so in der Nähe von CompilerVersion("3.5");

Der Link passt zwar nicht ganz zum Thema aber die angesprochene Zeile kommt vor.
 CompilerVersion

Ich weis dass Du was anderes hast, aber vielleicht konnte ich eine Richtung vorgeben.

// Edit:
bei mir hatte er ohne der richtigen Compiler version nämlich genau probleme mit dem Lambda, ohne lambda gings auch ohne Compilerversion
Wenn es bei dir ohne Lambda geht, würde ich in die gleiche Richtung tippen.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von spike24 am 15.10.2009 12:17.

15.10.2009 12:15 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.885
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

@spike24:

Danke für den Hinweis:

anscheinend geht auch so was:

C#-Code:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
class Program
{
    static void Main(string[] args)
    {
        var csc = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v3.5" } });
        var parameters = new CompilerParameters(new[] { "mscorlib.dll", "System.Core.dll" }, "foo.exe", true);
        parameters.GenerateExecutable = true;
        CompilerResults results = csc.CompileAssemblyFromSource(parameters,
        @"using System.Linq;
            class Program {
              public static void Main(string[] args) {
                var q = from i in Enumerable.Range(1,100)
                          where i % 2 == 0
                          select i;
              }
            }");
        results.Errors.Cast<CompilerError>().ToList().ForEach(error => Console.WriteLine(error.ErrorText));
    }
}

Wichtig ist anscheinend, dass es eben NICHT "3.5" sondern explizit "v3.5" heißen muss, d.h. das v ist wichtig.

Danke für den Hinweis. ;-)

d.h. in meinem Code habe ich jetzt:

C#-Code:
        public CReflectiveEvaluator()
            : this(new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v3.5" } }))
        {
        }

geschrieben. Was tatsächlich eine Änderung bewirkt, nur kann jetzt der Typ zur Laufzeit nicht erstellt werden. Die Kompilierung schlägt aber nicht mehr fehl.

EDIT:

Ich hab auf den falschen Namespace zugegriffen. Den gesamten Typnamen habe ich vollqualifiert einfach aus

C#-Code:
compilerResults.CompiledAssembly.GetTypes()

mit dem Debugger ermittelt. Jetzt lässt sich alles übersetzen. UND.... (Test).... Geil! Läuft. Problem gelöst.

Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von dr4g0n76 am 20.02.2020 12:03.

15.10.2009 12:32 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dN!3L dN!3L ist männlich
myCSharp.de-Poweruser/ Experte

avatar-2985.png


Dabei seit: 13.08.2004
Beiträge: 2.891


dN!3L ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top



Zitat von dr4g0n76:
C#-Code:
results.Errors.Cast<CompilerError>().ToList().ForEach(error => Console.WriteLine(error.ErrorText));

Wenn man einen Hammer hat, sieht alles aus wie ein Nagel... großes Grinsen
15.10.2009 12:41 Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.885
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

@spike24: Danke, deine Lösung hats gebracht. Super Tipp!

@dN!3L: LOL. ;-) Hatte das aus einem Beispiel. Quasi zur gleichen Zeit entdeckt wie Spike den Tipp gepostet hatte:

 c# 3.0 / 3.5 und codedom
15.10.2009 12:50 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.885
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hintergrund: Hier noch was ich damit gebastelt hab und warum:

C#-Code:
            string sText = new LambdaScript().Source.Replace("{0}", "Color.FromArgb(255-c.R, 255-c.G, 255-c.B)");

            object obj = ev.Eval(sText, "LambdaScript", "Test", new object[] { (Bitmap)this.BackgroundImage });

Ein Benutzer soll einen Ausdruck zur Laufzeit eingeben können.

Daraus werden dann bestimmte Lambdafunktionen generiert, die dann zur Laufzeit pixelweise auf z.B. ein Bild angewendet werden können.

Auf die Idee kam ich als ich

 Fast and Simple Bitmap Filter

und kurz danach dann

 Steve's Techtalk C#: Image Processing and Lambda Expressions

gelesen hatte.
15.10.2009 12:55 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dN!3L dN!3L ist männlich
myCSharp.de-Poweruser/ Experte

avatar-2985.png


Dabei seit: 13.08.2004
Beiträge: 2.891


dN!3L ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Kleine Ergänzung:

Zitat von spike24:
und da musste ich dem CodeDom Compiler sagen das ich 3.5 haben will [...]
bei mir hatte er ohne der richtigen Compiler version nämlich genau probleme mit dem Lambda, ohne lambda gings auch ohne Compilerversion

Das liegt daran, dass Lambdaausdrücke/Expressions ein Compilerfeature/C# 3.0-Feature (nicht zu verwechseln mit .NET-Framework-Version) sind.

Allerdings hätte ich erwartet, dass der aktuellste Compiler/die neueste C#-Version benutzt wird. Wieder was über CodeDOM gelernt...

Gruß,
dN!3L
15.10.2009 13:05 Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.885
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Testprojekt zu Runtimelambdas

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hier noch das Testprojekt dazu.

Und die Erklärung:

WindowsFormsApplication1 ist das Projekt mit der Form.
LambdaImageProcessingTools enthält die Routinen zum probieren

und ScriptCompiler2 ist eine Weiterentwicklung des Runtime-Compilers von FormelEditor bzw. Funktionsplotter, mit dem Unterschied zu früher, dass jetzt beliebige Objekte hin- und hergereicht werden können, wie ihr seht.

In diesem Fall eben ein Bild, das reingesteckt, über den Runtime-Lambda-Ausdruck verarbeitet, und dann wieder als Hintergrundbild der Form angezeigt wird.

Es wird also wirklich in den Lambda-Ausdruck reinkompiliert was in die Textbox eingegeben wird.

Das ganze ist nur ein Probierprojekt. Funktioniert aber super, solange beim Eintippen keine Fehler passieren.

EDIT: Ach ja, ganz vergessen, wichtig! Um ein Bild zu laden, Hintergrund mit Links doppelklicken, sonst gibts ne Exception oder evtl. andere Fehler


Dateianhang:
unknown RuntimeLambdas.rar (135 KB, 202 mal heruntergeladen)

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von dr4g0n76 am 15.10.2009 15:08.

15.10.2009 14:58 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Zwischen diesen beiden Beiträgen liegen mehr als 2 Monate.
dN!3L dN!3L ist männlich
myCSharp.de-Poweruser/ Experte

avatar-2985.png


Dabei seit: 13.08.2004
Beiträge: 2.891


dN!3L ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo zusammen,

Zitat von spike24:
und da musste ich dem CodeDom Compiler sagen das ich 3.5 haben will

Bekommt man eigentlich irgendwie raus, welche Compilerversion man (maximal) zur Verfügung hat?
Mit Environment.Version kommt man ja an die CLR-Version, aber die stimmt ja nicht mit der Compilerversion überein...

Gruß,
dN!3L
15.12.2009 15:26 Beiträge des Benutzers | zu Buddylist hinzufügen
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.885
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top



Zitat von dN!3L:
Zitat von dr4g0n76:
C#-Code:
results.Errors.Cast<CompilerError>().ToList().ForEach(error => Console.WriteLine(error.ErrorText));

Wenn man einen Hammer hat, sieht alles aus wie ein Nagel... großes Grinsen

Ist das eigentlich positiv oder negativ gemeint?!

EDIT/EDIT: smile wie gehen hier nochmal die richtigen Smilies?! ^^

Dieser Beitrag wurde 4 mal editiert, zum letzten Mal von dr4g0n76 am 12.01.2010 16:42.

12.01.2010 16:40 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
spike24 spike24 ist männlich
myCSharp.de-Mitglied

Dabei seit: 01.02.2008
Beiträge: 443
Herkunft: Steiermark Österreich


spike24 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich glaube weder noch, meines Erachtens beschreibt es eher die Situation, dass man etwas neues gelernt hat und mit diesem neuen wissen versucht alle bestehenden Probleme zu lösen.
 Regular Expressions
13.01.2010 09:47 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Zwischen diesen beiden Beiträgen liegen mehr als 6 Monate.
dr4g0n76
myCSharp.de-Poweruser/ Experte

avatar-1768.jpg


Dabei seit: 07.07.2005
Beiträge: 2.885
Entwicklungsumgebung: SharpDevelop/VS.NET
Herkunft: Deutschland

Themenstarter Thema begonnen von dr4g0n76

dr4g0n76 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Falls es jemanden interessiert, inzwischen habe ich auch folgendes gelöst:

LINQ Ausdruck zur Laufzeit übergeben.

Im eigentlichen geht das analog mit der selben Technik.
30.07.2010 15:08 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 10 Jahre.
Der letzte Beitrag ist älter als 9 Jahre.
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 01.04.2020 05:53