C#学习(二)匿名方法和委托的多种使用方式

前言

上次简单介绍了委托的概念和使用,今天继续,并且引入匿名方法的概念,匿名方法在很多语言里面都有,比如Python、js、java8,尤其js,前端小伙伴可能深受js回调地狱之苦,这里面匿名方法功不可没。

js的匿名方法就像这样: 这还没用lambda,因为我想下篇再介绍lambda。

document.querySelector('.btn').onclick = function () { };

Python的大概这样:

max = lambda a : a + 1

几个概念

实例委托

一旦声明了委托类型,委托对象必须使用 new 关键字来创建,且与一个特定的方法有关。当创建委托时,传递到 new 语句的参数就像方法调用一样书写,但是不带有参数。

多播委托

委托对象可使用 "+" 运算符进行合并。一个合并委托调用它所合并的两个委托。只有相同类型的委托可被合并。"-" 运算符可用于从合并的委托中移除组件委托。 使用委托的这个有用的特点,您可以创建一个委托被调用时要调用的方法的调用列表。这被称为委托的 多播(multicasting),也叫组播。

事件

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

事件在类中声明且生成,且通过使用同一个类或其他类中的委托与事件处理程序关联。包含事件的类用于发布事件。这被称为 发布器(publisher) 类。其他接受该事件的类被称为 订阅器(subscriber) 类。事件使用 发布-订阅(publisher-subscriber) 模型。

  • 发布器(publisher)是一个包含事件和委托定义的对象。事件和委托之间的联系也定义在这个对象中。发布器(publisher)类的对象调用这个事件,并通知其他的对象。
  • 订阅器(subscriber) 是一个接受事件并提供事件处理程序的对象。在发布器(publisher)类中的委托调用订阅器(subscriber)类中的方法(事件处理程序)。

关于事件的详细使用我会在后面的笔记上记录。

上代码

先上笔记代码,里面有详细的注释:

using System;

namespace DelegateAndEvent
{
    class Program
    {
        delegate void voidDelegate();

        delegate int intDelegate();

        delegate int doubleParamsDelegate(int num1, int num2);

        static void Main(string[] args)
        {
            // 定义一个多播委托
            voidDelegate d1 = T1;
            d1 += T2;
            d1 += T3;
            d1 += T4;

            // 执行委托
            // 会同时执行t1,t2,t3,t4四个方法
            d1();

            intDelegate d2 = Q1;
            d2 += Q2;
            d2 += Q3;

            Console.WriteLine("");
            Console.WriteLine("");

            // 执行
            // 会得到最后一个返回值,
            Console.WriteLine(d2());

            // 两种委托赋值方式
            d1 = T1;
            d1 = new voidDelegate(T1);

            // 利用委托将函数作为参数传递
            Func(T1);
            Func(T2);

            // 匿名方法
            // 定义匿名方法委托
            voidDelegate anonymousMethod = delegate { Console.WriteLine("hello"); };
            // 作为参数传递
            Func(anonymousMethod);

            // 定义有参数和返回值的匿名方法
            doubleParamsDelegate max = delegate(int num1, int num2) { return num1 > num2 ? num1 : num2; };
            // 换成lambda表达式
            max = (a, b) => a > b ? a : b;
            max(1, 2);
        }

        static void T1()
        {
            Console.WriteLine("1");
        }

        static void T2()
        {
            Console.WriteLine("2");
        }

        static void T3()
        {
            Console.WriteLine("3");
        }

        static void T4()
        {
            Console.WriteLine("4");
        }

        static int Q1()
        {
            return 1;
        }

        static int Q2()
        {
            return 2;
        }

        static int Q3()
        {
            return 3;
        }

        static void Func(voidDelegate func)
        {
            func();
        }
    }
}

就这样,C#的匿名方法就是new一个委托,不过基本没人用这个,因为远古版本的C#就已经支持lambda表达式了,lambda就是定义匿名方法的简便方式,而且又优雅,下篇我再记录lambda表达式的使用。

本文主要记录委托的多种使用方法,如传值、事件、传递函数参数等。

还有更多练习代码等我整理出来放到github上。

欢迎交流

交流问题请在微信公众号后台留言,每一条信息我都会回复哈~ - 微信公众号:画星星高手 - 打代码直播间:https://live.bilibili.com/11883038 - 知乎:https://www.zhihu.com/people/dealiaxy - 简书:https://www.jianshu.com/u/965b95853b9f