浅析C#---委托和事件
在C#开发中,有时我们需要实现这样的情况:只要新添加一个对象,就要执行一系列的方法。如果每次挨个调用,这样既浪费时间,又造成代码冗余。这个时候我们就可以使用委托来建立一个方法链条,设置好后,可以让一个对象依次去执行这个链条上的各个方法。这样的结果就是:简化了代码,提高了效率,提高了代码的可维护性。
究竟什么是委托呢?事件有何委托有什么关系呢?
一、定义
委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。
事件是一种特殊的委托,它在某些操作哦 发生时自动地发出通知。
二、使用
2.1、委托的使用
委托是一个能够引用方法的对象,能够调用它所指的方法。而且,在成宿运行七届,同一个委托可以条用不同的方法,只要改变它的引用的方法即可。所有委托类型的基类是System.Delegate类。
2.1.1、声明
像其他类一样,委托在使用之前也需要声明。委托类型声明将创建一个协定,该协定指定一个或多个方法签名。委托是委托类型的实例,它可以引用静态方法或实例方法。
语法:delegate-modifiers(修饰符) delegate(需使用的关键字) return-type(返回类型) identifier(类型名称)
2.1.2、注册方法
如果一个方法要注册到委托中,则该方法的签名必须与该委托所指定的签名完全匹配(即两者返回类型和方法参数须相同,参数具体的名称可以不同)
2.1.3、实例化委托
委托作为一个类,在使用前必须有实例化的过程。其实例化可以创建委托类型的实例,并向该实例注册方法列表。委托类型的实例的方法列表可以为静态方法,实例方法或者另外的委托。
下面可以通过一个实例我们来理解一下。
internal
delegate int
MyDelegate(int i);
//声明委托
class
Program
{
//声明一个实例方法Method1(int i)
public
int Method1(int i)
{
Console.WriteLine("调用实例方法Method1(int i)");
return i;
}
//声明一个静态方法Method2(int i)
public
static int Method2(int i)
{
Console.WriteLine("调用实例方法Method2(int i)");
return i;
}
static
void Main(string[] args)
{
Program p =new
Program();
MyDelegate dDelegate =new
MyDelegate(p.Method1); //将Method1注册到dDelegate中,并实例化dDelegate
int i = dDelegate(10);
Console.WriteLine("i的值为:" + i);
MyDelegate dMyDelegate =new
MyDelegate(Program.Method2); //将Method2注册到dMyDelegate中,并实例化dDelegate
int j =dMyDelegate(20);
Console.WriteLine("j的值为:" + j);
Console.ReadKey();
}
}
2.1.4构建方法列表
使用委托可以将多个方法绑定到同一个委托变量,当调用此变量是,可以一次调用所有绑定的方法。
方法列表可以包含一个或多个方法。
2.1.5调用
委托是一个方法链条,因此调用委托实例就相当于调用了该委托实例半酣的所有方法。如果一个调用列表包含多个方法是,当该委托实例被调用是,它将按照调用列表中的方法注册顺序依次调用每一个方法(通过下面例子的运行结果可以看出)。
下面我们用一个例子说明一下
internal
delegate int
MyDelegate(int i);
//声明委托
class
Program
{
//声明一个实例方法Method1(int i)
public
int Method1(int i)
{
Console.WriteLine("调用实例方法Method1(int i)");
return i;
}
//声明一个静态方法Method2(int i)
public
static int Method2(int i)
{
Console.WriteLine("调用实例方法Method2(int i)");
return i;
}
static
void Main(string[] args)
{
Program p =new
Program();
MyDelegate dDelegate1 =new
MyDelegate(p.Method1); //将Method1注册到dDelegate中,并实例化dDelegate
MyDelegate dDelegate2 =new
MyDelegate(Program.Method2); //将Method2注册到dMyDelegate中,并实例化dDelegate
MyDelegate dDelegate3 =dDelegate1 + dDelegate2; //给委托dDelegate3实例注册方法
MyDelegate dDelegate4 =dDelegate3 - dDelegate2; //给委托dDelegate4实例移除方法
int i1 =dDelegate1(20);Console.WriteLine("i1的值为:" + i1);
int i2 = dDelegate2(20);Console.WriteLine("i2的值为:" + i2);
int i3 =dDelegate3(20);Console.WriteLine("i3的值为:" + i3);
int i4 =dDelegate4(20);Console.WriteLine("i4的值为:" + i4);
Console.ReadKey();
}
}
执行结果:
2.2事件的使用
事件是某些操作发生时自动地发出通知。时间构建在委托的基础上,它是一种信号机制。程序员可以通过提供事件处理程序为相应的时间添加可执行代码。当事件触发时,将调用改时间事先定义的方法。
2.2.1声明
事件是一种特殊类型的委托,它包含两个参数:指示事件源的“对象源”(sender)参数和封装事件的其他任何相关信息的e参数。
事件的声明分为:(1)声明事件的委托;(2)声明事件的本身
2.2.2注册和移除
一个事件声明之后,改时间的默认值为null,如果希望该事件执行事先指定的操作,则首先向该事件注册方法列表。注册事件可以使用“+=”运算符,同时我们也可以移除事件(使用“-=”运算符)
2.2.3调用
声明一个事件之后,如果没有向该事件注册方法那么该事件的值为空。因此在调用事件时,往往需要检查该事件是否为空。
通过下面一个例子我们来看看事件是如何使用的。
namespace 事件
{
//声明委托
public
delegate void
EventHandler(object sender,
EventArgs e);
class
Program
{
//声明一个事件
public
event EventHandler Print;
//声明一个方法
public
void Method1(object sender,
EventArgs e)
{
Console.WriteLine("方法F1()");
}
//声明一个方法
public
void Method2(object sender,
EventArgs e)
{
Console.WriteLine("方法F2()");
}
static
void Main(string[] args)
{
Program program =new
Program();
program.Print += new
EventHandler(program.Method1); //注册Method1方法
program.Print += new
EventHandler(program.Method2); //注册Method2方法
Console.WriteLine("事件中的方法列表:");
if (program .Print !=null)
{
program.Print(null,null);
}
Console.WriteLine("");
program.Print -= new
EventHandler(program.Method1); //移除Method1方法
Console.WriteLine("移除方法Method1之后:");
if (program.Print !=
null)
{
program.Print(null,null);
}
Console.ReadKey();
}
}
}
运行结果: