C# 的Reflection非常有用,可以用它创作出更加通用,扩展性更好的程序(Reflection的效率会低一些)。Reflection用的最多的地方是在子程序的DLL有其他人开发的时候,主程序通过Reflection调用DLL的方法完成额外的任务。有时候主程序需要跟子程序DLL进行交互的时候,尤其是子程序耗时比较长的时候,我们需要反馈执行进度(异步执行),这个时候就需要用到Delegate来给子程序类绑定主程序的界面更新函数。
相信大家对于通过Refelection的MethodInfo的Invoke()方法来执行DLL的方法 和PropertyInfo来获得和设置属性值的操作都很清楚。但是如何在主程序中给子程序的委托挂载函数呢?这个资料不是很多。这里就贴一下代码,给大家一些启发。
着重看下面的函数: private void HookUpEventHandler(Type libType, object libInstance, string libEventName, string HandlerFunctionName)
//主程序
public partial class Form1 : Form
{
//此函数assign给子程序返回进度并更新界面
public void ReportProgress_Function(int i)
{
backgroundWorker1.ReportProgress(i);
}
//****** 此函数用来给子程序的对象assign委托 ******
private void HookUpEventHandler(Type libType, object libInstance, string libEventName, string HandlerFunctionName)
{
EventInfo ei = libType.GetEvent(libEventName); //Event info
Type tDelegate = ei.EventHandlerType; //子程序内委托的类型
MethodInfo miHandler = typeof(Form1).GetMethod(HandlerFunctionName); //上面的ReportProgress_Function()函数
Delegate d = Delegate.CreateDelegate(tDelegate, this, miHandler);//创建委托
MethodInfo addHandler = ei.GetAddMethod();
Object[] evParam = { d };
if(libInstance!=null)
addHandler.Invoke(libInstance, evParam);//给子程序类实力添加事件函数
}
//... ...
private void Form1_Load(object sender, EventArgs e)
{
Assembly assembly = Assembly.LoadFile(DllPath); //子程序DLL的路径
string ns = "namespace"; //子程序的命名空间
string cn = assembly.GetName().Name; //子程序主类的名称
labelClassName.Text ="Clas="+ cn;
//Get type and instance
Type t = assembly.GetType(ns +"." + cn);//子程序主类的类型
object inst = Activator.CreateInstance(t);//子程序主类的实例
if (inst != null)
{
//Assign Event functions
HookUpEventHandler(t, inst, "ProgressChanged", "ReportProgress_Function");//为子程序的类实例添加事件函数
//... ...
}
//子程序
public delegate void ProgressChangedEventHandler(int i);
public delegate void ExtractionCompleteEventHandler(DataSet ds);
public class etsLogLoader
{
//report parsing progress event
public event ProgressChangedEventHandler ProgressChanged;
//... ...
}