Frage

Was ich versuche, ist, einem Benutzer zu erlauben, eine Methode in ein Textfeld zu schreiben und meinen Code diese Methode aufrufen zu lassen.Dies wird schließlich in einem Demo-Applet zur Optimierung einer Zielfunktion verwendet.

Ich habe also mit einer Beispielkonsolenanwendung gearbeitet, habe aber Probleme.Ich habe Stack Overflow, Codeproject und andere Quellen überprüft und bin an dem Punkt angelangt, an dem ich den Code kompilieren kann.Aber ich weiß nicht, wie ich es aufrufe und nur auf eine Methode zugreife.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Reflection;

namespace CodeCompilerTest
{
    class Program
    {
        static void Main(string[] args)
        {
            CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");

            CompilerParameters parameters = new CompilerParameters();
            //parameters.GenerateExecutable = false;
            parameters.GenerateInMemory = true;
            //parameters.OutputAssembly = "Output.dll";

            string SourceString = @"
                                   using System;
                                   using System.Collections.Generic;
                                   using System.Text;

                                   namespace testone 
                                   {
                                        public class myclass
                                        {
                                            public double Main()
                                            {
                                                return testd(5,8);
                                            }

                                            public double testd(double a, double b)
                                            { 
                                                return a+b;
                                            } 
                                        } 
                                    }";

            CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, SourceString);

            if (results.Errors.Count > 0)
            {
                foreach (CompilerError CompErr in results.Errors)
                {
                    Console.WriteLine("Line number " + CompErr.Line + ", Error Number: " + CompErr.ErrorNumber + ", '" + CompErr.ErrorText + ";");
                }
                Console.ReadLine();
            }

            Assembly mAssembly = results.CompiledAssembly;
            Type scripttype = mAssembly.GetType("myclass");
            Object rslt = new Object();
            Object[] argin = {5, 8};
            //rslt  = scripttype.GetMethod("Main").Invoke(null, null);
            rslt = scripttype.InvokeMember("Main", BindingFlags.InvokeMethod | BindingFlags.Public |BindingFlags.Static, null, null, null);
            Console.WriteLine(((double)rslt).ToString());
            Console.ReadLine();
        }
    }
}

Ich habe verschiedene Kombinationen zum Aufrufen von Invoke für die Methode ausprobiert und erhalte immer wieder Fehler.Ich möchte, dass der Benutzer eine Funktion wie diese definiert:

public double funcname(double x, double y)
{
    return x+y;
}

Und dann könnte ich einfach funcname direkt aufrufen.Wenn dies nicht machbar ist, nehme ich, was ich an dieser Stelle bekommen kann.

Jede Hilfe oder Anleitung wäre dankbar.Danke.

War es hilfreich?

Lösung

Sie müssen den Namespace in die einschließen GetType Anruf.
(Oder entfernen Sie den Namespace aus der Quelle)

Vielleicht möchten Sie lieber anrufen GetTypes() und sehen Sie stattdessen alle in der Assembly definierten Typen.

Andere Tipps

Ich glaube, dieser Artikel wird Ihnen dabei helfen, über Schnittstellen direkt auf die Methode zuzugreifenhttp://www.codeproject.com/Articles/26312/Dynamic-Code-Integration-with-CodeDom

Möglicherweise ist das Folgende nicht direkt für Ihre Anfrage relevant, aber ich glaube, dass Sie Activator verwenden müssen, um eine Instanz der Klasse zu erstellen, damit Sie die aufrufen können testd Methode Ich meine, Ihr Code definiert ist kein Objekt, nur Klassendefinition.
Auch ich habe verwendet GetTypes()[0] Weil GetType() hat bei mir nicht funktioniert

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Reflection;

namespace CodeCompilerTest
{
    class Program
    {
        static void Main(string[] args)
        {
            CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");

            CompilerParameters parameters = new CompilerParameters();
            //parameters.GenerateExecutable = false;
            parameters.GenerateInMemory = true;
            //parameters.OutputAssembly = "Output.dll";

            string SourceString = @"
                                   using System;
                                   using System.Collections.Generic;
                                   using System.Text;

                                   namespace testone 
                                   {
                                        public class myclass
                                        {
                                            public double testd(double a, double b)
                                            { 
                                                return a+b;
                                            } 
                                        } 
                                    }";

            CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, SourceString);

            if (results.Errors.Count > 0)
            {
                foreach (CompilerError CompErr in results.Errors)
                {
                    Console.WriteLine("Line number " + CompErr.Line + ", Error Number: " + CompErr.ErrorNumber + ", '" + CompErr.ErrorText + ";");
                }
                Console.ReadLine();
            }

            Assembly mAssembly = results.CompiledAssembly;
            Type scripttype = mAssembly.GetTypes()[0];
            Object myObject = Activator.CreateInstance(scripttype);
            double  rsltd = 0.0;
            Object[] argin = { 5.0, 8.0 };
            rsltd  =(double) scripttype.GetMethod("testd").Invoke(myObject,argin);
          //  object rslt = new object();
           // rslt = scripttype.InvokeMember("testd", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, null);
       Console.WriteLine(rsltd.ToString());
       Console.ReadLine();
        }
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top