首页 > 技术文章 > 委托-lambda表达式

rush-peng 2020-07-16 09:20 原文



1.什么是委托

委托和类是平级单位,委托是持有一个或多个方法的对象。执行委托的时候,委托就会执行他所 “持有” 的方法。
(如果你有c语言背景,可以把它想象成函数指针,他是一种安全的指针类型)

调用委托的的时候,其包含的每一个方法都会被执行。
委托要求,定义的签名和返回类型必须一致。



建立委托需要注意的地方:

  • 委托和类是同级别的。
  • 写起来和普通的方法一样,(就是把函数名改成了委托名)
  • Main 函数是个函数。

因为大部分的委托需要重用,而事件不用,所以前者写在类外边,后者写在类里边。

一般 委托 写在类的外边,并且用public声明。

委托只有一个规矩,就是输入输出一样就行,那他属于一个委托,你可以把它想象成一个黑管子,只管进来的和出去的和约定的一样就行,不用管他里面是啥。

使用委托要注意的地方

  • 调用带返回值的委托,委托的返回值是最后执行方法的返回值。
  • 调用带引用参数的委托(即带 ref),引用参数的值会在调用间变换。
  • 函数返回类型时 void 的,可以不用带return 语句,非void 的都要带



下边是用 Lambder 实现委托的例子:

    delegate int   Prints(int x);
    delegate void  Printm(ref int x);
    class Program
    {
        static void Main()
        {
            Server server = new Server();
            
            //声明一个委托.
            Prints prints;
            prints = server.PrintA;  // 声明委托的时候,委托写在左边
            prints += server.PrintB; // 声明委托的时候,委托写在左边
            var resultt = prints(2); // 使用委托的时候,委托写在右边
            
      //带有返回值的这种,最后一个委托的返回值是最后的结果;
            Console.WriteLine("最终的参数"+resultt);

            Printm printm = server.Add1;
            printm += server.Add2;
            int x = 2;
            printm(ref x);
            Console.WriteLine("使用ref调用后的结果"+x);
            Console.WriteLine("*************************");


   // lambder 表达式,在是需要查询数据的时候,可以直接使用箭头来表示查询语句;
   //形如 (参数)=> 操作
   // lamber 实际上是调用了委托;
   // lambder 当委托有 ref 或者 out 必须要注明参数类型,
   // 其他时候,不一定要注明参数类型;
            Prints prints1 = x => x += 8;
            Console.WriteLine(prints1(3));
        }
    }

Server 类

  class Server
    {
        public int PrintA(int x)
        {
            Console.WriteLine("A********" + x);
            x += 3;
            return x;
        }

        public int PrintB(int x)
        {
            Console.WriteLine("B********" + x);
            x += 6;
            return x;
        }

        public void Add1(ref int x) { x += 1; } 
        public void Add2(ref int x) { x += 4; } 

        //指名是int类型的要加return
        public int add(int x) { return  x += 8; }
    }



在实际中。一般都是用 .net core 封装好的委托

委托说白了,就是函数指针。在 .net core 中。一般不提倡自己建委托,一般是使用 .net core 自带的委托,有两个 一个是Fun < int ,int, int >, 一个是Action < int, int ,int >.如果有返回类型就用 fun,没有返回类型就用Action。看下边的例子,结合使用了lambda表达式。

  class Program
    {
        static void Main(string[] args)
        {
            var m = Compare.showCompar(5, 8, (x, y) => x > y);
            Console.WriteLine(m);
        }
    }
    class Compare
    {
        public static int showCompar(int a, int b, Func<int, int, bool> Comp)
        {
            int c;
            if (Comp(a, b))
            {
                c = a;
            }
            else
            {
                c = b;
            }
            return c;
        }
    }


lambda表达式:

lambda 表达式其实本质就是匿名函数。只不过是省略了很多编译器可以推算出来的声明,

使用lambda表达式需要注意一下几点:

  • lambda表达式必须要将参数列表放在圆括号里
  • 带有 ref 的要写上参数。
  • 虽然lambda表达式允许包含任意数量的语句,但是一般限制在两三个语句之内
  • lambda表达式中,在linq语句中,可以理解为 “满足****条件的”。在其他地方理解为 “用于 ”
  • lambder 表达式,在查询参数的时候,可以直接使用 => 来表示查询
  • lambder 的形式,(参数) => 操作
  • lambder 使用在委托当中,若委托有ref 或out 参数,此时必须注明类型。
  • 带有 ref 关键字的,后边要跟上参数类型。

参考文献:

  1. https://www.cnblogs.com/zhaoyl9/p/12162697.html
  2. https://www.bilibili.com/video/BV1Ht41137R1/?p=4
  3. C# 中的委托和事件(详解:简单易懂的讲解)
  4. c#经典面试题—猫叫,主人醒,老鼠跑(事件的处理)
  5. https://blog.csdn.net/shangrila_ftd/article/details/70148922
  6. 苹果降价引发疯抢的源码
  7. https://zhidao.baidu.com/question/202695971.html

推荐阅读