【问题标题】:How to dynamically call a method in C#? [duplicate]如何在 C# 中动态调用方法? [复制]
【发布时间】:2010-07-15 10:49:37
【问题描述】:

我有一个方法:

  add(int x,int y)

我也有:

int a = 5;
int b = 6;
string s = "add";

是否可以使用字符串s调用add(a,b)

【问题讨论】:

  • if (s == "add") { add(a,b); }这个?

标签: c#


【解决方案1】:

如何在 c# 中做到这一点?

使用反射。

add 必须是某种类型的成员,所以(删掉很多细节):

typeof(MyType).GetMethod("add").Invoke(null, new [] {arg1, arg2})

这假定add 是静态的(否则Invoke 的第一个参数是对象),我不需要额外的参数来唯一标识GetMethod 调用中的方法。

【讨论】:

  • @DavidStratton 它将与private 成员一起使用:使用GetMethod 的重载之一,该重载采用BindingFlags 参数和BindingFlags.NonPublic
  • 我们可以使用 "Func" 代替 Refection 吗?
  • @Sreekumar 不,因为要创建 lambda,您需要在编译时修复或构建表达式树。后者动态完成需要使用反射。
【解决方案2】:

使用反射 - 尝试Type.GetMethod 方法

类似

MethodInfo addMethod = this.GetType().GetMethod("add");
object result = addMethod.Invoke(this, new object[] { x, y } );

您失去了强类型和编译时检查——invoke 不知道该方法需要多少个参数,它们的类型是什么以及返回值的实际类型是什么。因此,如果您没有正确处理,事情可能会在运行时失败。

速度也慢。

【讨论】:

  • 知道如何以 await 方式进行此调用
  • 我遇到的唯一问题是thisnull
【解决方案3】:

如果函数在编译时已知并且您只想避免编写 switch 语句。

设置:

Dictionary<string, Func<int, int, int>> functions =
  new Dictionary<string, Func<int, int, int>>();

functions["add"] = this.add;
functions["subtract"] = this.subtract;

调用者:

string functionName = "add";
int x = 1;
int y = 2;

int z = functions[functionName](x, y);

【讨论】:

    【解决方案4】:

    你可以使用反射。

    using System;
    using System.Reflection;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                Program p = new Program();
                Type t = p.GetType();
                MethodInfo mi = t.GetMethod("add", BindingFlags.NonPublic | BindingFlags.Instance);
                string result = mi.Invoke(p, new object[] {4, 5}).ToString();
                Console.WriteLine("Result = " + result);
                Console.ReadLine();
            }
    
            private int add(int x, int y)
            {
                return x + y;
            }
        }
    }
    

    【讨论】:

      【解决方案5】:

      @Richard 的回答很棒。稍微扩展一下:

      这在您动态创建未知类型的对象并需要调用其方法的情况下很有用:

      var do = xs.Deserialize(new XmlTextReader(ms)); // example - XML deserialization
      do.GetType().GetMethod("myMethodName").Invoke(do, new [] {arg1, arg2});
      

      因为在编译时do 只是一个Object

      【讨论】:

      • 我怎样才能让这个方法可以等待?
      • 您遇到什么问题,请详细说明。
      • 我想异步调用这个方法。我找到了解决方案。我将其键入为这样的任务。 await (Task)do.GetType().GetMethod("myMethodName").Invoke(do, new [] {arg1, arg2});
      猜你喜欢
      • 1970-01-01
      • 2015-11-18
      • 1970-01-01
      • 1970-01-01
      • 2013-01-26
      • 2011-07-18
      • 2013-05-20
      • 1970-01-01
      • 2014-02-24
      相关资源
      最近更新 更多