C# 通过将函数名称作为字符串传递来动态调用任何函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/801070/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 01:44:07  来源:igfitidea点击:

Dynamically invoking any function by passing function name as string

c#reflectionfunctioninstance

提问by Josh

How do I automate the process of getting an instance created and its function executed dynamically?

如何使创建实例并动态执行其功能的过程自动化?

Thanks

谢谢

Edit: Need an option to pass parameters too. Thanks

编辑:也需要一个选项来传递参数。谢谢

采纳答案by Jon Skeet

Do you just want to call a parameterless constructor to create the instance? Is the type specified as a string as well, or can you make it a generic method? For example:

你只是想调用一个无参数的构造函数来创建实例吗?类型是否也指定为字符串,或者您可以将其设为通用方法吗?例如:

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

or

或者

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

回答by Fredrik M?rk

Assuming that the method you want to invoke does not take any parameters:

假设您要调用的方法不带任何参数:

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

回答by Manish Basantani

I think your problem is little too generic here, I am providing a solution with certain assumptions here.

我认为您的问题在这里不太通用,我在这里提供了具有某些假设的解决方案。

Assumption: you have a typeName (string), methodName (string), and a parameter (of SomeType).

假设:您有一个 typeName(字符串)、methodName(字符串)和一个参数(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 });  
    } 

let me know know if my assumptions are wrong.

如果我的假设有误,请告诉我。

回答by Nader Shirazie

To invoke a constructor, Activator.CreateInstancewill do the trick. It has a bunch of overloads to make your life easier.

要调用构造函数,Activator.CreateInstance将起作用。它有一堆重载,让你的生活更轻松。

If your constructor is parameterless:

如果您的构造函数是无参数的

object instance = Activator.CreateInstance(type)

If you need parameters:

如果您需要参数

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

To invoke, a method, once you have the Typeobject you can call GetMethodto get the method, and then Invoke(with or without parameters) to invoke it. Should you need it, Invoke will also give you the return value of the function you're calling (or null if its a void method),

要调用一个方法,一旦您拥有Type对象,您就可以调用它GetMethod来获取该方法,然后Invoke(带或不带参数)调用它。如果您需要它,Invoke 还会为您提供您正在调用的函数的返回值(如果它是一个 void 方法,则为 null),

For a slightly more detailed sample (paste into a console app and go):

对于更详细的示例(粘贴到控制台应用程序中):

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

回答by chirag pathak

To pass the parameters dynamically Here I have taken params string[] args, because different functions have different number of parameters so.

动态传递参数这里我取了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);   

    }