Delegate
1、个人对delegate的理解
delegate 委托,将函数当做变量来操作,调用委托实例时会调用它绑定的函数。
2、委托的定义
委托的声明原型是
delegate <函数返回类型> <委托名> (<函数参数>);
例子:
public delegate void CheckDelegate(int number,string str);//定义委托,可以注册一个返回类型为void,并且参数为一个int的函数。(注意 参数要严格对称,定义的委托是怎样的,多少个参数,注册的函数就应该是这种形式,数量的参数)
public void GetNumber (int i,string p)
{
Console.WriteLine(i.ToString()+p);
Console.ReadLine();
}
CheckDelegate _myChecker = new CheckDelegate(GetNumber);//实例化
_myChecker(10,"SSR");//调用
现在我们就可以像使用函数一样来使用委托了,在上面的例子中现在执行_myChecker()就等同于执行GetNumber(),最关键的是现在函数GetNumber相当于放在了变量当中,它可以传递给其它的CheckDelegate对象,而且可以作为函数参数传递到其他函数内,也可以作为函数的返回类型
3、匿名函数初始化委托
被赋予委托的函数一般都是通过委托实例来调用,很少会直接调用函数本身,这样就让这个函数名变得无足轻重。(其实如果不算委托的其他功能,直接调用函数会比使用委托更方便)。
在.net 2.0的时候考虑到这种情况,于是匿名函数就诞生了,由于匿名函数没有名字所以必须要用一个委托实例来引用它,定义匿名函数就是为了初始化委托
匿名函数初始化委托的原型:
<委托类型> <实例化名>=new <委托类型>(delegate(<函数参数>){函数体});
例子:
static void Main(string[] args)
{
CheckDelegate _myChecker2 = new CheckDelegate(delegate(int i, string str) { Console.WriteLine(i.ToString() + str); Console.ReadLine(); });
CheckDelegate _myChecker = new CheckDelegate(GetNumber);
_myChecker(10,"SSR");
_myChecker2(20, "SSR");
}
static void GetNumber(int i, string str)
{
Console.WriteLine(i.ToString()+str);
Console.ReadLine();
}
4、泛型委托
泛型委托原型:
delegate <T1> <委托名> <T1,T2,T3…> (T1 t1,T2 t2,T3 t3…)
delegate //↑返回值
例子:
public delegate void CheckDoubleDel<T1,T2>(T1 t1,T2 t2);//定义有两个泛型(T1,T2)的委托,T2作为委托函数返回类型,T1作为委托函数参数类型
static void Main(string[] args)
{
CheckDoubleDel<int, string> _myChecker4 = new CheckDoubleDel<int, string>(GetNumber);
//将泛型委托委托<T1,T2>实例化为<int,string>,即表示有一个int类型参数且返回类型是int的函数,所以将GetNumber用来实例化委托
_myChecker(40,"SSR");
}
5、委托的多播性
多播性是指,一个委托可以注册一个或以上的函数,用+=连起来,执行委托的时候,会按照注册顺序,执行已经注册的函数。
函数注册委托的原型:
<委托类型> <实例化名>+=new <委托类型>(<注册函数>)
例子:CheckDelegate _checkDelegate=new CheckDelegate(CheckMod);//将函数CheckMod注册到委托实例_checkDelegate上
在.net 2.0开始可以直接将匹配的函数注册到实例化委托:
<委托类型> <实例化名>+=<注册函数>
例子:
CheckDelegate _myChecker5 += GetNumber;
CheckDelegate _myChecker5 = GetNumber;
CheckDelegate _myChecker5 = new CheckDelegate(GetNumber);
//实例化委托的三种方法
//接下来是连续注册
CheckDelegate _myChecker5 += GetNumber;
CheckDelegate _myChecker5 += GetNumber;
CheckDelegate _myChecker5 += GetNumber;
//算上一开始的实例化 实际上 这个委托注册了四个相同的函数,因此,单单这个_myChecker5就会执行4次GetNumber();
_myChecker(50,"SSR");
实际上使用+=符号的时候会判断 如果此时委托还没有实例化(委托实例为null),它会自动用+=右边的函数实例化委托
如果此时委托已经实例化,它会只把+=右边的函数注册到委托实例上
另外有一点需要注意的是,如果对注册了函数的委托实例从新使用=号赋值,相当于是重新实例化了委托,之前在上面注册的函数和委托实例之间也不再产生任何关系,后面的例子会讲到这点
当然有+=注册函数到委托,也有-=解除注册
例子:_checkDelegate -= new CheckDelegate( GetNumber);//解除 GetNumber对_checkDelegate的注册
_checkDelegate-= GetNumber;//.net 2.0开始可以用这种方式解除注册
6、绑定事件
首先定义一个委托
public delegate void TestEventHandler(string s);
public event TestEventHandler eventTest = new TestEventHandler ();
//eventTest发生时,触发的函数
public void fun_event(string s )
{
Console.writeLine(s);
}
//绑定
eventTest += new TestEventHandler(fun_event)
//调用
eventTest("abcdefg");