• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

.net----委托和事件

武飞扬头像
醉卧考场君莫笑
帮助1

委托

  • 委托是C#用来处理需用函数指针来处理的情况的

  • 委托是完全面向对象的(同时封装了对象实例和方法),是类型安全的

  • 委托可保存对方法的引用的类,但只能对于其签名匹配的方法进行引用

  • 委托声明定义一个从 System.Delegate 类派生的类

  • 委托实例封装了一个调用列表,该列表列出了一个或多个方法,每个方法称为一个可调用实体

  • 对于实例方法,可调用实体由该方法和一个相关联的实例组成

声明

[委托修饰符] delegate 返回值类型 委托名 ([形参列表]);

实例化

委托名 委托实例名 = new 委托名(匹配方法);

调用

委托实例名(实参列表);

将类型安全的函数指针(方法)作为其他方法的参数进行传递,从而实现函数回调方法

 delegate void D(int x);       // 声明委托
    class C
    {
        public static void M1(int i){Console.WriteLine("C.M1:"   i);}
        public static void M2(int i){Console.WriteLine("C.M2:"   i);}
        public void M3(int i){Console.WriteLine("C.M3:"   i);}
    }
    
class Test
    {
        static void Main()
        {
            D d1 = new D(C.M1);  //使用new关键字,创建委托对象,指向类静态方法
            d1(-1);              //调用M1
            D d2 = C.M2;        //使用赋值运算符,创建委托对象,指向类静态方法
            d2(-2);             //调用M2
            C objc = new C();
            D d3 = new D(objc.M3); //使用new关键字,创建委托对象,指向对象实例方法
            d2(-3);              //调用M3
            Console.ReadKey();
        }
    }

委托:匿名方法委托

  • 无需先声明类或结构以及与委托匹配的方法,而是在创建委托的实例时,直接声明与委托匹配的方法的代码块(匿名方法)
delegate void Printer(string s); //声明委托
class TestClass
{  
      static void Main()
      {  // 使用匿名方法实例化delegate类
         Printer p = delegate(string j)
         { Console.WriteLine(j); };
         p("使用匿名方法的委托的调用。"); 
         //匿名delegate调用结果
         Console.ReadKey();
      }
  }     

多播委托

委托也可以包含多个方法,这种委托称为多播委托

  • 调用多播委托实例,则按顺序依次调用多播委托实例封装的调用列表中的多个方法
  • 声明多播委托时,其返回类型必须为void
  • 三个静态方法:Combine, Remove, RemoveAll
  • 多播委托通过 或 = 向多播委托实例封装的调用列表中添加方法;通过 – 或 – = 从多播委托实例封装的调用列表中删除方法
delegate void D(int x);
    class C
    {
        public static void M1(int i) { Console.WriteLine("C.M1: "   i);} 
        public static void M2(int i) { Console.WriteLine("C.M2: "   i);}
    }
    class Test
    {
        static void Main()
        {  D cd1 = new D(C.M1);  cd1(-1); //调用 M1
           D cd2 = new D(C.M2);  cd2(-2); //调用M2
           D cd3 = cd1   cd2; 	cd3(10);   //先调用M1,然后调用M2
           cd3 -= cd1;  cd3(20); //删除M1,调用M2
           cd3 -= cd2;        //删除M2后,调用列表为null
           // cd3(70);         //抛出System.NullReferenceException异常
           cd3 -= cd1;        //没有M1可删除,但不报错
           Console.ReadKey();
        }
    }
学新通

委托:委托的异步调用

学新通

委托:委托的兼容性

  • 与委托向对应的方法不必与委托签名完全匹配

  • 方法M与委托类型D兼容条件:

  • D和M的参数数目相同,且各自对应参数具有相同的ref或out修饰符

  • 对于每个ref或out参数,D中的参数类型与M中的参数类型相同

  • 存在从M的返回类型到D的返回类型的标识或隐式引用转换。即允许方法具有的派生返回类型比委托中定义的更多(协变)

  • 每一个值参数(没有 ref 或 out 修饰符的参数)都存在从D中的参数类型到M中的对应参数类型的标识或隐式引用转换。允许方法具有的派生参数类型比委托类型中的更少(逆变)

事件

处理机制;事件的声明、订阅和取消;.NET Framework事件模型

  • 一种使对象或类能够提供通知的成员

  • 类或对象可以通过事件向其他类或对象通知发生的相关事情

  • 发送(或引发)事件的类称为“发行者”(生产者),接收(或处理)事件的类称为“订户”(消费者)

  • 事件是对象发送的消息,以发信号通知操作的发生

  • 在 .NET Framework 类库中,事件是基于 EventHandler 委托和 EventArgs 基类的

事件实际上是委托的一种特殊形式,C#使用一种委托模型来实现事件

  • 事件模型分为事件生产者和事件消费者,其处理机制大致可以分为下列4步:

  • 在事件生产者类中声明一个事件成员,即某种事件处理委托(简称为事件委托)的实例(多播事件委托实例);

  • 在事件消费者类中声明与事件委托相匹配的事件处理方法;

  • 通过“ =”向多播事件委托实例封装的调用列表中添加事件处理方法,或通过“-=”从多播事件委托实例封装的调用列表中删除事件处理方法;

  • 在事件生产者类中添加有关发生事件的代码,即当满足某种条件时(发生事件),则调用委托,即调用多播事件委托实例封装的调用列表中添加的事件处理方法。如果没有订阅,即事件实例为Null,则不作任何处理
    学新通

button.Click  = new EventHandler(this.Button_Click);//按钮单击事件

private void Button_Click(object sender, EventArgs e) // 声明按钮单击事件处理方法
{
      box.BackColor = System.Drawing.Color.Green;  // 文本框背景色改为绿色
}

事件的声明、订阅和取消

  • 声明
    [修饰符] event 事件委托名 事件名;
    事件委托名(sender, e)

  • 订阅和取消
    对象.事件名 =委托实例;
    对象.事件名 -=委托实例;

 //声明事件处理委托
    public delegate void SampleEventHandler(object sender, EventArgs e);
    public class Publisher 
    {
        public event SampleEventHandler SampleEvent; //声明事件
        protected virtual void RaiseSampleEvent()     //产生事件
        {  //若不需要传递消息参数,可直接使用EventArgs对象
            SampleEvent(this, new EventArgs());    //引发事件
        }
    }
public class Subscriber
    {
        public static void Method1(object sender, EventArgs e)
        {
            Console.WriteLine("To Do Something...");
        }
        public static void Method2(object sender, EventArgs e)
        {
            Console.WriteLine("To Do Something...");
        }
}
public static void Main()
{  / /创建委托实例
            SampleEventHandler d1 = new SampleEventHandler(Subscriber.Method1);
            Publisher p = new Publisher(); 
//订阅事件
            p.SampleEvent  = d1;
            p.SampleEvent  = new SampleEventHandler(Subscriber.Method2);
//订阅事件
            p.SampleEvent -= d1;       //取消事件
            Console.ReadKey();
        }

事件:实现的步骤

  • 声明提供事件数据的类,从System.EventArgs派生

  • 声明事件处理委托

  • 声明引发事件的类

  • 在事件生产类中,声明事件

  • 在事件生产类中,实现产生事件的代码

  • 声明处理事件的类

  • 在事件消费类中,声明事件处理方法

  • 在事件消费类中,订阅或取消事件

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhiebcib
系列文章
更多 icon
同类精品
更多 icon
继续加载