您的位置:首页 > 编程语言 > C#

C#委托和事件

2016-06-16 11:08 295 查看
其实这部分内容对于 .NET程序员而言应该是老生常谈了,但鉴于团队内常有成员对委托和事件感到混乱,因而记录下来以供分享。

委托是C#第一个版本就引入的特性,特点如下

1. 类似于C++中的函数指针;

2. 允许方法像变量一样赋值;

3. 用以作回调操作;

4. 委托以链表的方式记录委托实例;

5. 委托实例中使用的类型并不需要与委托声明中的类型完全吻合;

6. 在C#2.0中引入了匿名委托,C#3.0引入了Lambda表达式作为委托实例。

通常我们据说的委托包括了委托声明和委托实例两种概念,委托声明是声明了一个委托样式,而委托实例则是与委托声明类型相符的变量,该变量记录了一系列与委托声明形式类似的方法,如

class Program
{
public delegate void HandlerMethod();

public static void MammalsHandler()
{
}

public static void DogsHandler()
{
}

static void Test()
{
HandlerMethod handlerMammals = MammalsHandler;
handlerMammals += DogsHandler;
}
}


中,public delegate Mammals HandlerMethod()是委托声明,声明HandlerMethod是一种委托类型,任何无参数且无返回值函数都可以被赋值给这种委托类型的实例,例如

HandlerMethod handlerMammals = MammalsHandler;

handlerMammals += DogsHandler;

对委托实例handlerMammals赋值之后,handlerMammals委托列表中记录了两个方法,当用户invoke handlerMammals时,MammalsHandler和DogsHandler方法会依次被调用,而通过handlerMammals-=DogsHandler之类的语句可以对移除委托实例中的委托列表。

通常而言,我们使用到委托是为了实现对象的回调操作,这就要求一个对象实现的委托链表赋值可以在对象外进行操作,但该委托实例的方法列表不能在对象外部被调用, 可以看到通过上述声明和实例化的方式,需要很多代码才能进行这种可见性隔离,此时事件就派上用场了。事件的使用方法如下;

public delegate void HandlerMethod();
class EventTest
{
public event HandlerMethod OnMammalHandled;
public void HandleMammal()
{
if(null!=OnMammalHandled)
OnMammalHandled();
}
}
static void Test()
{
EventTest et = new EventTest();
et.OnMammalHandled+=MammalsHandler;
et.OnMammalHandled+=DogsHandler;
et.HandleMammal();
et.OnMammalHandled-=MammalsHandler;
et.OnMammalHandled-=DogsHandler;
}

public static void MammalsHandler()
{
}

public static void DogsHandler()
{
}


与上一个例子相关不大,但在这个例子中,事件OnMammalHandled作为一个代理,其在类实例之外只允许通过+=/-=方法进行赋值,而在类内等同于完整的委托实例,通过引入事件,可以完美地实现我们需要的回调方法效果,即对外部只具赋值可视性,对内部具有全部可视性。

同样,事件的赋值也可以使用匿名函数或者Lambda表达式,例如

static void Test()
{
EventTest et = new EventTest();
et.OnMammalHandled+=delegate(){};
et.OnMammalHandled+=()=>{};
et.HandleMammal();
}


通过强大的委托、事件匿名函数和Lambda表达式等特性,我们可以使回调代码变得清晰简单,并且可读性更高。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  .net c# 委托 事件