C#下的关键字delegate实际上是告诉编译器生成一个继承自MulticastDelegate的密封类。而该类的主要职责是创建函数的回调环境。
而生成的密封类定义如下:
namespace DefineNameSpace{
public delegate string DefineDelegate(bool a, bool b, bool c);
public class OtherClassOne
{
public DefineDelegate myDelegate;
}
public class OtherClassTwo{}
}编译器实际会生成:
namespace DefineNameSpace{
public sealed class DefineDelegate :System.MulticastDelegate
{
public string Invoke(bool a, bool b, bool c);
public IAsyncResult BeginInvoke(bool a, bool b, bool c, AsyncCallback cb, object state);
public string EndInvoce(IAsyncResult result);
}
public class OtherClassOne
{
public DefineDelegate myDelegate;
}
public class OtherClassTwo{}
}另外,MulticastDelegate类和Delegate类的定义如下:
public abstract class MulticastDelegate : Delegate
{
//添加到委托的方法列表
public sealed override Delegate[] GetInvactionList();
//重载操作符
public static bool operator == (MulticastDelegate d1, MulticastDelegate d2);
public static bool operator != (MulticastDelegate d1, MulticastDelegate d2);
//用来在内部管理委托所维护的方法列表
private IntPtr _invocationCount;
private object _invocationList;
}Delegate类的定义如下:
public abstract class Delegate : ICloneable, ISerializeable
{
//与函数列表交互的方法
。。。Combine。。。
。。。Remove。。。
。。。RemoveAll。。。
//扩展委托目标的属性
public MethodInfo Method {get;}//反射,委托所维护的静态方法或实例方法的信息
public object Target {get;}//只有委托的方法定义在类实例时不为null,代表委托方法的对象。
}对委托 DefineDelegate 的说明:
- 声明一个委托,实际上是创建了一个类,这个类继承自MulticastDelegate。
- 需要使用委托,必须在某个类的内部顶一个一个该委托类的委托实例或委托对象。例如OtherClassOne里的实例定义:public DefineDelegate myDelegate;。
- Invoke为同步调用方法。返回值与参数列表与用delegate关键字定义时一致。由于一个委托对象可以维护一个委托方法列表,并通过操作符+=进行添加,所以Invoke会依次调用添加到委托实例的方法列表。
- BeginInvoke和EndInvoke为一对操作,在对委托进行异步调用的时候使用。
对委托 DefineDelegate 异步调用的说明:
- 调用一个委托对象的BeginInvoke方法时,系统会为该对象创建一个工作线程,并在该线程内调用委托对象所维护的方法列表。
- 主调线程代码应该创建一个AsyncCallback的委托对象传递给BeginInvoke。如以下代码所示:
private void someMethod()
{
... ...
AsyncCallBack delegateCb = new AsyncCallback(this.invokeComplete);
string completeInfo = "delegate async handle over";
myDelegate.BeginInvoke(ParamsList..., delegateCb, completeInfo);//将会在另一个线程中进行处理
... ...
}
private void invokeComplete(IAsyncResult result)
{
AsyncResult ar = (AsyncResult)result;
DefineDelegate tmpDelegate = (DefineDelegate)ar.AsyncDelegate;
string delegateResult = tmpDelegate.EndInvoke(result);//获取委托方法的处理结果
string completeInfo = (string)result.AsyncState;//传入BeginInvoke的state参数
}
本文探讨了C#中的委托(delegate)机制,指出声明委托实际上是创建了一个继承自MulticastDelegate的类。委托实例用于存储方法列表,Invoke方法用于同步调用这些方法,而BeginInvoke和EndInvoke则用于异步调用,其中BeginInvoke启动新的工作线程执行方法,主调线程通常配合AsyncCallback进行异步处理。


被折叠的 条评论
为什么被折叠?



