Подтвердить что ты не робот

Динамически вызывать любую функцию, передавая имя функции как строку

Как автоматизировать процесс создания экземпляра и его функции, выполняемой динамически?

Спасибо

Изменить: вам нужна опция для передачи параметров. Благодаря

4b9b3361

Ответ 1

Вы просто хотите вызвать конструктор без параметров для создания экземпляра? Является ли тип указанным как строка, или вы можете сделать его универсальным методом? Например:

// 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 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);
}

или

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

Ответ 2

Чтобы вызвать конструктор, Activator.CreateInstance будет делать трюк. У этого есть куча перегрузок, чтобы облегчить вашу жизнь.

Если ваш конструктор без параметров:

object instance = Activator.CreateInstance(type)

Если вам нужны параметры:

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

Чтобы вызвать метод, когда у вас есть объект Type, вы можете вызвать GetMethod, чтобы получить method, а затем Invoke (с параметрами или без них) для его вызова. Если вам это нужно, Invoke также даст вам возвращаемое значение функции, которую вы вызываете (или null, если это метод void),

Для немного более детального примера (вставьте в консольное приложение и идите):

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;
        }
    }
}

Ответ 3

Предполагая, что метод, который вы хотите вызвать, не принимает никаких параметров:

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);
}

Ответ 4

Я думаю, что ваша проблема здесь слишком невелика, я предлагаю решение с некоторыми предположениями здесь.

Предположение: у вас есть typeName (string), methodName (string) и параметр (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 });  
    } 

сообщите мне, не ошибаются ли мои предположения.

Ответ 5

Чтобы динамически передавать параметры Здесь я взял params string [] args, потому что разные функции имеют различное количество параметров, поэтому.

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);   

    }