1.委托的定义
委托的声明原型是
delegate<函数返回类型><委托名>(<函数参数>)
例子: public delegate void CheckDelegate(int number);//定义了一个委托
CheckDelegate,它可以注册返回void类型且有一个int作为参数的函数
这样就定义了一个委托,但是委托在.NET内相当于声明了一个类,类如果不实例化为对象,很多功能是没有办法使用的,
委托也是如此。
2.委托的实例化
委托实例化的原型是
<委托类型><实例化名>=new<委托类型>(<注册函数>)
例子: CheckDelegate _checkDelegate = CheckMod;//用函数CheckMod实例化上面的
CheckDelegate 委托为_checkDelegate
现在我们就可以像使用函数一样来使用委托了,在上面的例子中现在执行
_checkDelegate()就等同于执行CheckMod(),最关键的是现在函数CheckMod相当于放在了变量当中,
它可以传递给其它的CheckDelegate引用对象,而且可以作为函数参数传递到其他函数中,也可以作为函数的
返回类型。
2.用匿名函数初始化委托
匿名函数初始化委托的原型:
<委托类型> <实例化名> = new <委托类型>(delegate(<函数参数>){函数体});
也可以是<委托类型> <实例化名>=delegate(<函数参数>){函数体};
3.泛型委托
委托也支持泛型的使用
泛型委托原型:
delegate <T1> <委托名><T1,T2,T3...> (T1 t1,T2 t2,T3 t3...)
例子:
delegate T2 A<T1,T2>(T1 t);//定义有两个泛型(T1,T2)的委托,T2作为委托函数返回类型,T1作为委托函数参数类型
例1:
class Program { public delegate void Func1(int i); public delegate int Func2(int i); static void PrintNumber(int i) { Console.WriteLine(i); } static void Main(string[] args) { Func1 _func = new Func1(PrintNumber); _func(5); Console.ReadLine(); } }
例2:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { delegate void Func1(int i); delegate int Func2(int i); static Func1 t1 = new Func1(delegate(int i) { Console.WriteLine(i); }); static Func2 t2; static void Main(string[] args) { t2 = delegate(int j) { return j; }; t1(2); Console.WriteLine(t2(1)); } } }
例3:
class Program { //泛型委托 public delegate T2 A<T1,T2>(T1 t); static int test(int t){ return t; } static void Main(string[] args) { A<int,int> a = test; Console.WriteLine(a(5)); Console.ReadKey(); } }
例4:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication3 { public delegate int DelMath(int i);//定义委托类DelMath,该委托传入一个int类型参数, //返回一个int类型参数。 class Program { static DelMath dMath;//通过委托类型DelMath定义委托实例dMath static event DelMath eMath;//通过委托类型DelMath定义事件实例eMath /// <summary> /// 将传入的参数i自加后作为函数返回值 /// </summary> /// <param name="i"></param> /// <returns></returns> static int IncMath(int i) { i++; Console.WriteLine("IncMath has been invoked!"); return i; } static int DecMath(int i){ i--; Console.WriteLine("DecMath has been invoked!"); return i; } static void Main(string[] args) { int i = 10;//定义int 型变量i,初始化为10 dMath += IncMath;//先将IncMath函数注册到委托实例dMath dMath += DecMath;//再将DecMath函数注册到委托实例dMath Console.WriteLine("dMath returned:" + dMath(i).ToString()); eMath += IncMath; eMath += DecMath; Console.WriteLine("eMath returned:" + eMath(i).ToString()); Console.ReadKey(); } } }
4.事件
事件定义
event<委托类型> 事件名
委托: public delegate void CheckDelegate(int i);
例子: 事件:public event CheckDelegate checkEvent;
上面的例子声明了个事件叫checkEvent你会发现它只比声明委托实例前多了个关键字event
声明了事件后就可以实例化事件,注册函数到事件,解除事件函数注册其方法和委托的步骤如出一辙:
例子:checkEvent+=new CheckDelegate(CheckMod);//将函数CheckMod注册到事件checkEvent上
checkEvent+=CheckMod;//.net 2.0开始支持这种方法
checkEvent-=new CheckDelegate(CheckMod);//将函数CheckMod解除对事件checkEvent的注册
checkEvent-=CheckMod;//.net 2.0开始支持这种方法
5.委托与事件的联系:
从种种迹象都可以看出事件和委托实例是那么的相似,那么为什么不直接用委托还要用到事件呢?
其实事件就是对委托的封装。
就如同c#类中属性对字段的封装一样,其封装后可以在委托上封装更复杂的逻辑,下面我们来看c#中事件的两种声明方式,来了解事件对委托的封装
1)显式声明事件
其实显式声明事件就是要自己来手动实现隐式声明事件的一个委托实例
和两个函数:
event<委托类型> 事件名
{
add
{
//将函数注册到自己定义的委托实例
}
remove
{
//解除函数对自己定义的委托实例的注册
}
}
例1:
private CheckDelegate _checkDelegate; public event CheckDelegate checkEvent { add{ _checkDelete = Delegate.Combine(_checkDelete,value ) as CheckDelegate; } remove { _checkDelete = Delegate.Remove(_checkDelete, value) as CheckDelegate; } } using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication4 { public class ClassLibrary { public delegate void CheckDelegate(int number); public event CheckDelegate checkEvent; public void WriteInner(int n) { Console.WriteLine(n.ToString()); } public void InitEvent() { checkEvent = WriteInner;//对事件从新赋值 } public void Exec(int n) { checkEvent(n); } } }
例2:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication4 { class Temp //定义此类是为了在代码中展示函数对委托和事件的另外一种注册方式 { public delegate void TempDelegate(int u); public static TempDelegate td; public static event TempDelegate ed; } class Program { private static void CheckMod(int number) { if(number % 2==0) { Console.WriteLine("输入的是偶数"); } else { Console.WriteLine("输入的不是偶数"); } } private static void CheckPositive(int number) { if (number > 0) { Console.WriteLine("输入的是正数"); } else { Console.WriteLine("输入的不是正数"); } } static void Main(string[] args) { ClassLibrary cl = new ClassLibrary(); // cl.checkEvent = new ClassLibrary.CheckDelegate(CheckMod); cl.checkEvent += CheckMod; cl.checkEvent += CheckPositive; Console.WriteLine("cl的结果"); cl.Exec(50); Console.ReadKey(); } } }