C#编程入门20_委托、事件、Lambda表达式

声明委托

委托声明决定了可由该委托引用的方法。委托可指向一个与其具有相同签名的方法。

委托的声明和方法的声明时一样,只不过多了一个delegate修饰符

委托不是方法,而是一种类型
委托是引用类型

如下两种委托限定了回调方法的类型
public delegate int YyDelegate();
public delegate int MyDelegate (string s);
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

实例化委托

声明委托后,我们可以通过new关键字来创建委托。委托的构造方法中需要填入的是方法的名 ,注意不带有参数: 
例如: 
delegate void MyDelegate(); 
MyDelegate mydel = new MyDelegate(Test);

需要回调的方法: 
void Test() 

Console.WriteLine(“nn真帅”); 

我们还可以直接赋值: 
MyDelegate del = Test;


多播委托

委托对象可使用 “+” 运算符进行合并。一个合并委托调用它所合并的两个委托。只有相同类型的委托可被合并。”-” 运算符可用于从合并的委托中移除组件委托。

使用委托的这个有用的特点,您可以创建一个委托被调用时要调用的方法的调用列表。这被称为委托的 多播(multicasting),也叫组播

在生活办公中使用的打印机就是一个多播的一个实例: 
例如张三需要打印一个文件,打印耗时5分钟,李四也需要打印一个文件,那么李四只需要向打印机发出打印文件的命令即可,在打印张三的文件结束后,再打印李四的文件。如果李四反悔了,就可以撤销刚才的操作。


事件

事件(Event) 基本上说是一个用户操作,如按键、点击、鼠标移动等等,或者是一些出现,如系统生成的通知。应用程序需要在事件发生时响应事件。例如,中断。事件是用于进程间通信。


声明事件

在类的内部声明事件,首先必须声明该事件的委托类型。 
public delegate void BoilerLogHandler(string status); 
然后,声明事件本身,使用 event 关键字: 
// 基于上面的委托定义事件 
public event BoilerLogHandler BoilerEventLog;


使用事件实现观察者模式

发布者

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 事件案例1
{

    delegate void MyDelegate(string str);
    class Promulgator
    {
        public event MyDelegate handler;

        public void AddEvent(MyDelegate func)
        {
            handler += func;
        }

        public void SubEvent(MyDelegate func)
        {
            handler -= func;
        }

        public void ExeEvent(string str)
        {
            if (handler!=null)
            {
                handler.Invoke(str);
            }
        }
    }
}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

订阅者

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 事件案例1
{
    class Subscriber
    {
        private string name;

        public Subscriber(string name)
        {
            this.Name = name;
        }

        public string Name
        {
            get
            {
                return name;
            }

            set
            {
                name = value;
            }
        }

        public void Notice(string str)
        {
            Console.WriteLine("{0},{1}",Name,str);
        }
    }
}

   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

Program

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 事件案例1
{
    class Program
    {
        static void Main(string[] args)
        {
            Promulgator p = new Promulgator();
            Subscriber xiaoming = new Subscriber("小明");
            p.AddEvent(xiaoming.Notice);
            Subscriber wangyao = new Subscriber("王垚");
            p.AddEvent(wangyao.Notice);
            Subscriber yadong = new Subscriber("亚东");
            p.AddEvent(yadong.Notice);
            p.ExeEvent("老板来了,各就各位");
        }
    }
}

   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

Lambda表达式

在Framework 2.0 以前,声明委托的唯一方法是通过方法命名,从Framework 2.0 起,系统开始支持匿名方法。 
通过匿名方法,可以直接把一段代码绑定给事件,因此减少了实例化委托所需的编码系统开销。 
而在 Framework 3.0 开始,Lambda 表达式开始逐渐取代了匿名方法,作为编写内联代码的首选方式。总体来说,Lambda 表达式的作用是为了使用更简单的方式来编写匿名方法,彻底简化委托的使用方式。


Action

常用泛型委托:Action 
此委托由系统提供 无需声明 
Action 支持0~16个参数,可以按需求任意使用。

public delegate void Action()

public delegate void Action< T1>(T1 obj1) 
public delegate void Action< T1,T2> (T1 obj1, T2 obj2) 
public delegate void Action< T1,T2,T3> (T1 obj1, T2 obj2,T3 obj3) 
………… 
public delegate void Action< T1,T2,T3,……,T16> (T1 obj1, T2 obj2,T3 obj3,……,T16 obj16)

static void Main(string[] args)
{
    int x = 1000;
    Action action = () => x = x + 500;
    action.Invoke();

    Console.WriteLine("Result is : " + x);
}

static void Main(string[] args)
{
    Action<int> action = (x) =>
    {
        x = x + 500;
        Console.WriteLine("Result is : " + x);
    };
    action.Invoke(1000);

}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

Func

委托 Func 与 Action 相似,同样支持 0~16 个参数,不同之处在于Func 必须具有返回值 
public delegate TResult Func() 
public delegate TResult Func

static void Main(string[] args)
{
    Func<double, bool, double> func = Account;
    double result=func(1000, true);
    Console.WriteLine("Result is : "+result);
}
static double Account(double a,bool condition)
{
    if (condition)
        return a * 1.5;
    else
        return a * 2;
}

static void Main(string[] args)
{
      Func<double, bool, double> func = (a,condition) =>
      {
          if (condition)
          {
              return a * 1.5;
          }
          else
          {
              return a * 2;
          }
      };
      double result=func(1000, true);
      Console.WriteLine("Result is : "+result);
 }
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值