再探委托与事件

简介:


委托  

在这里补充两个对委托运用得比较少的示例:

一、将委托作为参数传递,然后再调用;

二、使用委托调用内部类中的方法;

 

示例一:委托作为参数

复制代码
ExpandedBlockStart.gif 委托作为参数.cs
using  System;
using  System.Collections.Generic;
using  System.Text;

namespace  委托作为参数
{
    
class  计算器
    {
        
public   delegate   int  delCalculate( int  a,  int  b);

        
//  将委托作为参数
         public   void  Fun( int  a,  int  b, delCalculate cal)
        {
            
if  (cal  !=   null )
            {
                Console.WriteLine(cal(a,b));
            }
        }

        
//  加法
         public   int  Add( int  a,  int  b)
        {
            
return  a  +  b;
        }
        
//  减法
         public   int  Reduce( int  a,  int  b)
        {
            
return  a  -  b;
        }
    }

    
class  Run
    {
        
static   void  Main( string [] args)
        {
            计算器 js 
=   new  计算器();

            
// 调用加法
            计算器.delCalculate d1  =   new  计算器.delCalculate(js.Add);
            js.Fun(
20 , 10 , d1);  // 将委托作为参数

            
// 调用减法
            js.Fun( 20 , 10 , new  计算器.delCalculate(js.Reduce));
        }
    }
}
复制代码


示例二:委托调用内部类的方法

复制代码
ExpandedBlockStart.gif 委托调用内部类的方法.cs
using  System;
using  System.Collections.Generic;
using  System.Text;

namespace  委托调用内部类的方法
{
    
class  Person
    {
        
public   delegate   void  myDelegate( string  str);

        
public   void  Fun( string  str)
        {
            Console.WriteLine(str);
        }

        
// 内部类的调用
         public   class  InnerClass
        {
            
public   void  SubFun( string  str)
            {
                Console.WriteLine(str);
            }
        }
    }

    
class  Program
    {
        
static   void  Main( string [] args)
        {
            Person p 
=   new  Person();
            
// 内部委托的实例化(用类名调用)
            Person.myDelegate pm1  =   new  Person.myDelegate(p.Fun);
            pm1(
" 内部委托调用的方法 " );

            
// 内部类 InnerClass
            Person.InnerClass pc  =   new  Person.InnerClass();
            Person.myDelegate pm2 
=   new  Person.myDelegate(pc.SubFun);
            pm2(
" 内部委托调用内部类的方法 " );
        }
    }
}
复制代码


 

事件

由于MSDN含混不清的误导,很多人会认为:事件就是一种受限的委托。但实际上不是!
事件与委托 的关系好比 字段与属性 的关系。
事件实际上是一种委托属性,只不过这个属性重载的不是赋值运算符,而是+=和-=运算符。

对于一个属性而言,对它的赋值和取值运算会被转换为两个方法的调用。
例如:obj.A 这个属性
obj.A = "aaa";       将调用 set 访问器:   set {  _a = value;  }
string a = obj.A;   将调用 get 访问器:   get {  return _a;  }

而事件也是一样,假设有一个事件obj.E,则下面的表达式也等同于后面的形式:
obj.E += d;              obj.add_E( d )
obj.E -= d;              obj.remove_E( d )


事件与属性的共同点:
事件也可以被继承;
事件也可以被重写;
事件也可以是虚的或者抽象的(表现在add和remove方法是抽象的或者虚的);

理论上,事件的add和remove方法也可以有不同的访问权限。


事件与属性的不同点:
属性是必须实现的,事件则不必(或者说,事件是最早出现的自动属性);

与自动属性一样,事件也会创建一个字段来保存对应的委托实例,而这个字段与事件同名且是私有。在C#中,你可以访问到这个字段,因为它真的就是一个字段。
换言之,在C#中写代码时,如果是在类的内部使用事件,其实就是引用那个自动生成的私有字段(委托字段)。
而在类的外部使用事件,是不同于在类的内部使用事件(因为这个字段是私有的,所以在类的外部也就访问不到)。

event 本质上所做的工作应该还是通过 delegate 来实现的,或者至少原理相同。event 关键字只不过是让CLR给所定义的 delegate 对象进行一个封装。
event 是通过对 delegate 的限制来封装一部分本来就不应该暴露在外的行为,从而更符合面向对象的思想(封装的原则)。


附加:
1、事件其实是由三个方法add、remove和raise组成的。但C#编译器总是不会生成raise方法。
2、自动事件不同的编译器实现是不同的,例如VB的编译器生成的私有字段是(事件名)Event。
3、Web开发中的Control也是事件驱动的。  



本文转自钢钢博客园博客,原文链接:http://www.cnblogs.com/xugang/archive/2010/04/28/1723254.html,如需转载请自行联系原作者

相关文章
观察者模式(委托和事件)——老板来了我不知道
观察者模式(委托和事件)——老板来了我不知道
开门小例子学习观察者模式&事件与委托
3.2.一个喊话人(喊话人有权限),多个拿钥匙开门的人(每个人负责不同的门):米老师大喊给我开一下水麒麟的门——>此时听到消息并且拿着水麒麟钥匙的人就会过来开门
委托和事件——老鼠跑和猫叫
委托和事件——老鼠跑和猫叫
|
C#
艾伟_转载:解惑答疑:C#委托和事件
  相信很多人一直为C#委托和事件所困惑,尤其是C#的初学者,学到这一部分会感觉比较困难,很有可能就放弃了,而且.NET对委托和事件封装得挺好,一般都不怎么用到自定义的委托和事件,所以放弃学习该技术就有了借口!   网上也有不少此类的文章,最具代表性的是张子阳的C#中的委托和事件这篇,写得的确很好,...
1367 0
|
C#
艾伟:C# 中的委托和事件
引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易。它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉得心里别(biè)得慌,混身不自在。
781 0
|
.NET
艾伟_转载:把委托说透(2):深入理解委托
在上一篇随笔中我们通过示例逐步引入了委托,并比较了委托和接口。本文将重点剖析委托的实质。 委托在本质上仍然是一个类,我们用delegate关键字声明的所有委托都继承自System.MulticastDelegate。
1079 0
|
C#
艾伟_转载:C#中的委托和事件-抛砖引玉
  最近在学习委托和事件,在书店里面看了好多书,但是都是迷迷的…… 今天在博客园里面看到了 张子阳 所写的博客C#中的委托和事件:http://www.tracefact.net/CSharp-Programming/Delegates-and-Events-in-CSharp.
1142 0
|
监控 C#
艾伟_转载:把委托说透(1):开始委托之旅 委托与接口
委托,本是一个非常基础的.NET概念,但前一阵子在园子里却引起轩然大波。先是Michael Tao的随笔让人们将委托的写法与茴香豆联系到了一起,接着老赵又用一系列文章分析委托写法的演变,并告诫“嘲笑孔乙己的朋友们,你们在一味鄙视“茴”的四种写法的同时,说不定也失去了一个了解中国传统文化的机会呢!”。
980 0