【发布时间】: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#
我有一个方法:
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#
如何在 c# 中做到这一点?
使用反射。
add 必须是某种类型的成员,所以(删掉很多细节):
typeof(MyType).GetMethod("add").Invoke(null, new [] {arg1, arg2})
这假定add 是静态的(否则Invoke 的第一个参数是对象),我不需要额外的参数来唯一标识GetMethod 调用中的方法。
【讨论】:
private 成员一起使用:使用GetMethod 的重载之一,该重载采用BindingFlags 参数和BindingFlags.NonPublic。
使用反射 - 尝试Type.GetMethod 方法
类似
MethodInfo addMethod = this.GetType().GetMethod("add");
object result = addMethod.Invoke(this, new object[] { x, y } );
您失去了强类型和编译时检查——invoke 不知道该方法需要多少个参数,它们的类型是什么以及返回值的实际类型是什么。因此,如果您没有正确处理,事情可能会在运行时失败。
速度也慢。
【讨论】:
this 是null
如果函数在编译时已知并且您只想避免编写 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);
【讨论】:
你可以使用反射。
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;
}
}
}
【讨论】:
@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});