运行时通过方法名调用方法






1.45/5 (6投票s)
2004年12月27日
3分钟阅读

51971

388
使用 Reflection.MethodInfo 类在运行时根据方法名称调用方法。
引言
我曾在 C# 留言板上发布了这个问题。 感谢 Daniel 找到了解决方案。
"大家好,我是 C# 新手。我正在编写一个小型应用程序。该应用程序将从一个平面文件中读取方法名称。然后使用与读取方法相同的名称在另一个类库中调用该方法。例如,我在平面文件中有一个名为“add”的方法,而另一个库是“Math”,那么我的应用程序应该调用“Math.add”,另一个库可能会更改,因此平面文件也会更改。这类似于我在 Unix 上的 C/C++ 程序中使用的 dlsym。这里可以做类似的事情吗? 提前感谢,此致,Jitesh"
为了理解这个主题,让我们首先了解一个关于这个主题的示例应用程序。
Application
假设您想编写一个引擎,该引擎使用一些搜索条件在数据库中进行搜索。我们称这个条件为“SomeFunduCriterea”。我们有两种实现此选项的标准。
选项 1:将其放入引擎本身。 这样做的问题是,_您_ 必须在条件更改的情况下修改引擎的源代码。如果其他人提出了其他条件,他将不得不从您那里获取代码并进行修改。
选项 2:制作一个类库,它是一个此类条件的集合。您的引擎只需使用这个库。现在您的引擎可以作为二进制文件分发。 而标准库作为源代码。因此,任何人都可以向其中添加自己的标准,并且仍然可以在不进行任何更改的情况下使用该引擎。
选项 2 始终是更好的选择。 这里的问题是,当我们尝试从引擎中调用条件库中的函数时。 引擎将在运行时如何知道在条件库中调用什么? 让我们看看解决方案。
解决方案
引擎应该调用的方法将在一个平面文件(主要是 XML 文件)中。这将是引擎的输入文件。该文件还将包含该方法的参数。我们将使用 System.Reflection
命名空间的 MethodInfo
类来调用我们用户在条件类中的方法。
怎么做呢?
我们将看一个示例来了解如何实现这一点。我们在一个名为 CExternal
的类中拥有我们的用户方法。
public class CExternal
{
public CExternal()
{}
// Our User Method
public string Fullname(string firstname, string lastname)
{
return (firstname + lastname);
}
}
我们的用户方法是 FullName
方法,它返回两个参数 firstname
和 lastname
的串联。此类可以在单独的类库中。
我们需要编写的下一个类是 CInvoker
,它调用该方法。
public class CInvoker
{
public CInvoker()
{}
public object InvokeMethod (string method, object[] args)
{
// create an object of the external class that
// implemented the method.
CExternal objExternal = new CExternal();
// get the type and methodinfo
Type typExternal = Type.GetType("MethodInvoke.CExternal");
MethodInfo methodInf = typExternal.GetMethod(method);
// invoke the method
object ret = methodInf.Invoke(objExternal, args);
// return object
return ret;
}
}
简单的步骤
- 首先,我们创建一个
CExternal
类的对象。 - 获取
CExternal
类的类型。 - 在此类型对象上调用
GetMethod
。 这需要方法的字符串名称。 (请记住我们的 XML 文件,即引擎的输入文件有此名称)。此方法将返回我们的MethodInfo
对象。(MethodInfo
继承自MethodBase
类。) - 最后调用
Invoke
方法。我们将传递它,我们的CExternal 对象
(第 1 行)和一个参数object[]
。
最后是这个 Invoke 类的驱动程序。 即我们在 CMain
类中的 main 方法。
public class CMain
{
public CMain()
{}
public static void Main()
{
CInvoker ink = new CInvoker();
string[] args = {"Jitesh" , "patil"};
ink.InvokeMethod("Fullname", args);
}
}
很简单吧。
感谢
- Daniel Turini.
- Microsoft
System.Reflection.MethodBase
和MethodInfo
。
参考
MSDN 链接到 MethodBase.Invoke()
方法。