委托简介 c#

委托简介 找?e佫~?  
委托是C#中的一种引用类型,类似于C/C++中的函数指针。与函数指针不同的是,委托是面向对象、类型安全的,而且委托可以引用静态方法和实例方法,而函数指针只能引用静态函数。委托主要用于 .NET Framework 中的事件处理程序和回调函数。 w^w僄?抴  
一个委托可以看作一个特殊的类,因而它的定义可以像常规类一样放在同样的位置。与其他类一样,委托必须先定义以后,再实例化。与类不同的是,实例化的委托没有与之相应的术语(类的实例化称作对象),作为区分我们将实例化的委托称为委托实例。 8: 粁膑;l  
函数指针 $<揩麊? 
为什么委托是类型安全的。C#中的委托和指针不一样,指针不通过MSIL而是直接和内存打交道,这也是指针不安全的原因所在,当然也是采用指针能够提高程序运行速度的缘故;委托不与内存打交道,而是把这一工作交给CLR去完成。CLR无法阻止将不安全的代码调用到本机(非托管)代码中或执行恶意操作。然而当代码是类型安全时,CLR的安全性强制机制确保代码不会访问本机代码,除非它有访问本机代码的权限。 诙涿坥( ? 
委托派生于基类System.Delegate,不过委托的定义和常规类的定义方法不太一样。委托的定义通过关键字delegate来定义: lbS辚/? 
b辭?  
public delegate int myDelegate(int x,int y); K??1?9? 
描Xp墄]? 
上面的代码定义了一个新委托,它可以封装任何返回为int,带有两个int类型参数的方法。任何一个方法无论是实例方法还是静态方法,只要他们的签名(参数类型在一个方法中的顺序)和定义的委托是一样的,都可以把他们封装到委托中去。这种签名方法正是保证委托是类型安全的手段之一。 荍 e{蹪? 
i榟甑U? 
委托的使用: /3i>s遻€  
using System;
public class MyClass
{
       public static void Main()
       {
              PrintStr myPrinter = new PrintStr();
              PrintHandler myHandler = null;
              myHandler += new PrintHandler(myPrinter.CallPrint);
// 将委托链接到方法,来实例化委托
              if(myHandler!=null)
                     myHandler("Hello World!");   
// 调用委托,相当于匿名调用委托所链接的方法
              Console.Read();
       }
}
public delegate void PrintHandler(string str);    // 声明委托类型
public class PrintStr
{              
       public void CallPrint(string input)
       {
              Console.WriteLine(input);
       }
}
在C#中使用委托方法: 嵇?:z鲞)  
创建委托所使用的方法必须和委托声明相一致(参数列表、返回值都一致) '耔?;&~  
利用 +=、-=来进行委托的链接、取消链接或直接使用Delegate.Combine和Delegate.Remove方法来实现 )瘌FF鮒  
可以使用MulticastDelegate的实例方法GetInvocationList()来获取委托链中所有的委托 t譶?謊辕8  
不能撰写包含 out 参数的委托 ;I?漏鞗E  
Z?qv戚楢? 
事件的简介 E?Ml%? 
C# 中的“事件”是当对象发生某些事情时,类向该类的客户提供通知的一种方法。 €P?骅,W溠Q  
1、事件的声明: ,箐?8?2  
声明的格式为:<access modifier> event <delegate type> EventName 習羚?  
因为使用委托来声明事件,所以在类里声明事件时,首先必须先声明该事件的委托类型<delegate type>(如果尚未声明的话)。在上面我们已经提到过了委托类型的声明,但是在.net framework下为事件使用的委托类型进行声明时有更严格的规定: 緳ju骐>应  
(1)、 事件的委托类型应采用两个参数; ?瞒Y詋y3  
(2)、两个参数分别是:指示事件源的“对象源”参数和封装事件的其他任何相关信息的“e”参数; .凤p竪颻埝  
(3)、“e”参数的类型应为EventArgs 类或派生自 EventArgs 类。 Q軳HB=? 
叫>W坐/~  
如下的定义: >G[p髓坬  
public delegate void PrintHandler(object sender,System.EventArgs e); Bh:B?擫a  
??(?俆D  
然后我们才能声明该委托类型的事件 n皦1g?Q  
例如: HP$豓嫲堋? 
public event PrintHandler Print; *俑s舰播? 
当事件发生时,将调用其客户提供给它的委托。 祴i唃裌#? 
餐鶃疗o燩  
2、调用事件: ?E瑸芺綒? 
  类声明了事件以后,可以就像处理所指示的委托类型的字段那样处理该事件。如果没有任何客户将委托与该事件绑定,则该字段将为空;否则该字段引用应在调用该事件时调用的委托。因此,调用事件时通常先检查是否为空,然后再调用事件。(调用事件,即触发事件,只能从声明该事件的类内进行 選H嫙?  
:Z岤憱髄|? 
if(Print != null) 噅戔氋??  
{ ??2放e|N  
    Print (this,e); 郍笛2R?g  
} H$?訁偟Bc  
鹟 ?奲 ? 
3、事件绑定: 仪"泷?啣s  
  从类的外面来看,事件就象类的一个公共成员,通过 类名.事件名 的形式来访问,但是只能对它做绑定和解除绑定的操作,而不能有其他操作。 諡T秘趺? 
e蘕唿钄 ? 
类名. Print += new PrintHandler(绑定的方法名) 罛6媌>1圿  
// 将某个方法绑定到Print事件上 訥瞢刮鈗?  
类名. Print -= new PrintHandler(绑定的方法名) 騻,8?剓  
// 将某个已绑定到Print事件上的方法从Print事件上解除 

using System;
public class MyClass
{
       private static bool check = true;
       public static void Main()
       {
              PrintStr print = new PrintStr();
              print.Print += new PrintHandler(print_Print);
              while(MyClass.check)
              {
                     print.AddNum();
              }
              System.Console.WriteLine("事件被激活,退出循环!");
       }

       private static void print_Print(string str)
       {
              MyClass.check = false;
       }
}

public delegate void PrintHandler(string str);    // 声明委托类型

public class PrintStr
{              
       public event PrintHandler Print;
       private int a = 0;

       public PrintStr()
       {
              Print = new PrintHandler(this.CallPrint);
       }
       public void CallPrint(string input)
       {
              System.Console.WriteLine(input);
       }
       public void AddNum()
       {
              a ++;
              if(a >= 10)
              {
                     Print("a已经等于10了。");
              }
       }
}
这段代码的作用就是,在不停的执行print.AddNum()时当a被累加到10的时候会激活一个事件,让这个循环终止运行。

using System;
namespace Events
{
    public delegate void NumberReachedEventHandler(object sender, NumberReachedEventArgs e);
    public class Counter
    {
        public event NumberReachedEventHandler NumberReached;
        public Counter()
        {
        }
        public void CountTo(int reachableNum)
        {
             NumberReachedEventArgs e = new NumberReachedEventArgs(reachableNum);
             OnNumberReached(e);
             return;
        }

        protected virtual void OnNumberReached(NumberReachedEventArgs e)
              //可以被重载
        {
            if(NumberReached!=null)
            {
                NumberReached(this, e);
            }
        }
    }

    public class NumberReachedEventArgs : EventArgs
    {
        private int _reached;
        public NumberReachedEventArgs(int num)
        {
            this._reached = num;
        }
        public int ReachedNumber
        {
            get
            {
                return _reached;
            }
        }
    }
}

 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值