委托
一:介绍
在C#中,委托是一种类型,属于引用类型,委托的关键字是delegate,委托的定义和类的定义一样,所以凡是能定义类的地方也是可以定义委托的。委托是一种可用于封装命名或匿名方法的引用类型。 委托类似于 C++ 中的函数指针;但是,委托是类型安全和可靠的
二:声明委托
//声明一个无参数无返回值的委托
public delegate void DelegateMethod();
//声明一个有一个参数,无返回值的委托
//public delegate void DelegateMethod(string str);
//声明一个无参数,有返回值的委托
//public delegate string DelegateMethod();
//声明一个有一个参数,有返回值的委托
//public delegate string DelegateMethod(string str);
//声明一个DelegateMethod 类型的对象,DelegateMethod 是类型,DelegateOption是对象
public DelegateMethod DelegateOption;
三:栗子
public delegate void DelegateMethod(string str); public void Use() { DelegateMethod dm = new DelegateMethod(TestUse); dm("小明"); } public void TestUse(string name) { Console.WriteLine("委托测试-"+name); }
四:部分源码
public abstract class Delegate : ICloneable, ISerializable { [ForceTokenStabilization, SecurityCritical] internal object _target; [SecurityCritical] internal object _methodBase; [ForceTokenStabilization, SecurityCritical] internal IntPtr _methodPtr; [ForceTokenStabilization, SecurityCritical] internal IntPtr _methodPtrAux;
}
_methodPtr 是指向该方法的指针.
_methodBase 是给委托赋值时传递的方法
五:泛型委托,Action和Func
①Action给我们提供的是只有参数而不带返回值的委托,
②Func给我们提供的是有参数有返回值的委托,Result表示返回值
action应用 public void Use() { Action<string> ac = TestUse; ac("小明"); } public void TestUse(string name) { Console.WriteLine("委托测试-"+name); }
func应用 public void Use() { Func<string, string> fc = TestUse; var result = fc("大名"); Console.WriteLine(result); } public string TestUse(string name) { return "测试" + name; }
泛型委托的好处
第一 : 可以减少我们委托的定义数量
第二 : 泛型是类型安全的
第三 : 方便进行协变和逆变
第四 : 简化代码
五:多播委托,委托链
public class DelegateUse { public delegate void DelegateMethod(); public DelegateMethod DelegateOption; public void TestUse() { Console.WriteLine("委托测试"); } public void GetTest() { Console.WriteLine("无参数委托"); } public void Test() { Console.WriteLine("无参数无返回值委托"); } public void RunDelegate() { DelegateOption.Invoke(); } }
DelegateUse du = new DelegateUse(); du.DelegateOption = new DelegateUse.DelegateMethod(du.Test); du.DelegateOption += new DelegateUse.DelegateMethod(du.TestUse); du.DelegateOption += new DelegateUse.DelegateMethod(du.GetTest); du.RunDelegate();
如果把"+"换成等于号,则只能显示最后一个委托的数据,前面的都被覆盖了
六:委托的异步调用
①委托对象有void Invoke , System.IAsyncResult BeginInvoke,void EndInvoke . 这三个构造函数
②EndInvoke 方法检索异步调用的结果。 在调用 BeginInvoke 之后随时可以调用该方法。 如果异步调用尚未完成,则 EndInvoke 会一直阻止调用线程,直到异步调用完成
Invoke : 委托回调函数时候的一种同步调用方式.
BeginInvoke : 委托回调函数时候的一种异步调用方式.和Invoke对立
EndInvoke : 异步调用,用于检索调用结果.
public delegate void DelegateMethod(string str); public void Use() { DelegateMethod dd = GetTest; var k = dd.BeginInvoke("canshu", null, null); dd.Invoke("参数"); dd.EndInvoke(k); Console.WriteLine(); } public void GetTest(string name) { Console.WriteLine("无参数委托----" + name); }
结果:
无参数委托----参数
无参数委托----canshu