如何通过方法的“名称”调用方法?

9

如果我有一个对象和它的类型,想要按名称(如“Method1”)调用某个方法,该怎么做呢?

我想做的事情是这样的:

Object o;
Type t;

// At this point I know, that 'o' actually has
// 't' as it's type.

// And I know that 't' definitely has a public method 'Method1'.

// So, I want to do something like:

Reflection.CallMethodByName(o, "Method1");

这是否有可能? 我意识到这会很慢,不方便,但不幸的是,在我的情况下我没有其他实现方式。

3个回答

11
您可以使用:

// Use BindingFlags for non-public methods etc
MethodInfo method = t.GetMethod("Method1");

// null means "no arguments". You can pass an object[] with arguments.
method.Invoke(o, null);

请参阅MethodBase.Invoke文档了解更多信息 - 例如传递参数。

如果你在使用C# 4并且在编译时知道方法名称,那么使用Stephen的dynamic方法可能会更快(并且绝对更易于阅读)。

当然,如果可能的话,将所涉及的类型实现一个已知的接口会更好。


@Peter:已修复 - 我以为第二个参数是“params”,但显然不是。 - Jon Skeet
1
为了证实Jon的速度评论,我编写了一个简单的基准测试。使用dynamic确实更快(20-25倍),无论是将dynamic赋值还是将GetMethod放置在测试循环内(这些会影响速度差异是20倍还是25倍)。当然,在某些情况下可能不会更快,并且在大多数程序中它可能不会成为瓶颈。没有什么花哨的东西,只是在staticnew StringBuilder上调用或调用函数sb.Append("A");(并在测试完成时输出长度)。 - Brian

11

如果具体的方法名称只在运行时才知道,那么您不能使用dynamic,需要使用类似于以下内容的东西:

t.GetMethod("Method1").Invoke(o, null);

假设Method1没有参数。如果有,你需要使用GetMethod的其中一个重载,并将参数作为Invoke的第二个参数传递。


1
这个答案已经在这里发布过了。 - Robert Harvey

8
最简单的方法是:
dynamic myObject = o;
myObject.Method1();

2
并不是我们所有人都在使用C# 4.0。 - Robert Harvey
2
这假设您在编译时知道该方法。 - Jon Skeet
3
我知道 't' 肯定有一个名为 'Method1' 的公共方法 - 我理解这是编译时的信息。 - Stephen Cleary

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接