Frage

Wie automatisieren ich den Prozess der Einführung einer Instanz erstellt und seine Funktion ausgeführt dynamisch?

Danke

Edit: eine Option benötigen Parameter zu übergeben. Dank

War es hilfreich?

Lösung

Wollen Sie nur einen parameterlosen Konstruktor rufen die Instanz zu schaffen? Ist der Typ als String angegeben als auch, oder können Sie es eine generische Methode? Zum Beispiel:

// All error checking omitted. In particular, check the results
// of Type.GetType, and make sure you call it with a fully qualified
// type name, including the assembly if it's not in mscorlib or
// the current assembly. The method has to be a public instance
// method with no parameters. (Use BindingFlags with GetMethod
// to change this.)
public void Invoke(string typeName, string methodName)
{
    Type type = Type.GetType(typeName);
    object instance = Activator.CreateInstance(type);
    MethodInfo method = type.GetMethod(methodName);
    method.Invoke(instance, null);
}

oder

public void Invoke<T>(string methodName) where T : new()
{
    T instance = new T();
    MethodInfo method = typeof(T).GetMethod(methodName);
    method.Invoke(instance, null);
}

Andere Tipps

einen Konstruktor aufzurufen, Activator.CreateInstance wird der Trick. Es hat eine Reihe von Überlastungen Ihr Leben leichter zu machen.

Wenn Ihr Konstruktor parameterlos :

object instance = Activator.CreateInstance(type)

Wenn Sie Parameter :

object instance =  Activator.CreateInstance(type, param1, param2)

aufzurufen, ist ein Verfahren, sobald Sie den Typen haben Objekt können Sie rufen Sie GetMethod die Methode und dann Invoke (mit oder ohne Parameter), um sie aufzurufen. Sollten Sie es brauchen, rufen Sie geben Ihnen auch den Rückgabewert der Funktion, die Sie anrufen (oder null, wenn es ein void-Methode),

Für eine etwas detailliertere Probe (Einfügen in eine Konsole app und gehen):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;

namespace Test
{
    public static class Invoker
    {
        public static object CreateAndInvoke(string typeName, object[] constructorArgs, string methodName, object[] methodArgs)
        {
            Type type = Type.GetType(typeName);
            object instance = Activator.CreateInstance(type, constructorArgs);

            MethodInfo method = type.GetMethod(methodName);
            return method.Invoke(instance, methodArgs);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // Default constructor, void method
            Invoker.CreateAndInvoke("Test.Tester", null, "TestMethod", null);

            // Constructor that takes a parameter
            Invoker.CreateAndInvoke("Test.Tester", new[] { "constructorParam" }, "TestMethodUsingValueFromConstructorAndArgs", new object[] { "moo", false });

            // Constructor that takes a parameter, invokes a method with a return value
            string result = (string)Invoker.CreateAndInvoke("Test.Tester", new object[] { "constructorValue" }, "GetContstructorValue", null);
            Console.WriteLine("Expect [constructorValue], got:" + result);

            Console.ReadKey(true);
        }
    }

    public class Tester
    {
        public string _testField;

        public Tester()
        {
        }

        public Tester(string arg)
        {
            _testField = arg;
        }

        public void TestMethod()
        {
            Console.WriteLine("Called TestMethod");
        }

        public void TestMethodWithArg(string arg)
        {
            Console.WriteLine("Called TestMethodWithArg: " + arg);
        }

        public void TestMethodUsingValueFromConstructorAndArgs(string arg, bool arg2)
        {
            Console.WriteLine("Called TestMethodUsingValueFromConstructorAndArg " + arg + " " + arg2 + " " + _testField);
        }

        public string GetContstructorValue()
        {
            return _testField;
        }
    }
}

Unter der Annahme, dass die Methode, die Sie aufrufen möchten keine Parameter übernehmen:

public void InvokeMethod(Type type, string methodName)
{
    object instance = Activator.CreateInstance(type);
    MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

    method.Invoke(instance, null);
}

Ich denke, Ihr Problem ist, etwas zu hier generisch, ich hier eine Lösung mit bestimmten Annahmen bin bereitstellt.

Annahme: Sie haben eine Typname (string), methoden (string) und ein Parameter (von Sometype)

.
public static void InvokeMethod(string typeName, string methodName, SomeType objSomeType) {
      Type type = Type.GetType(typeName);
      if(type==null) {
        return;
      }
      object instance = Activator.CreateInstance(type); //Type must have a parameter-less contructor, or no contructor.   
      MethodInfo methodInfo =type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public);
      if(methodInfo==null) {
        return;
      }
      methodInfo.Invoke(instance, new[] { objSomeType });  
    } 

Lassen Sie mich wissen, ob meine Annahmen falsch sind.

Um die Parameter übergeben dynamisch Hier habe ich params string [] args genommen, da verschiedene Funktionen so unterschiedliche Anzahl von Parametern haben.

public void Invoke(string typeName,string functionName,params string[] args)
    {

     Type type = Type.GetType(typeName);
     dynamic c=Activator.CreateInstance(type);
     //args contains the parameters(only string type)
     type.InvokeMember(functionName,BindingFlags.InvokeMethod,null,c,args);   

    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top