zoukankan      html  css  js  c++  java
  • C# 委托、Lambda表达式和事件——学习总结

    1.概括

      1.1、委托是寻址方法的.NET版本,类似C++中的指针。委托可以理解成指向函数的指针,它是类型安全的,定义了具体的参数和返回值。

      ——定义一个委托,实际上是定义一个类。委托是对方法的引用,如方法Func,把其功能交给委托的类来实现。

      ——委托的作用:结合泛型,可以实现功能上的扩展(如针对整型的函数,可以通过委托指向多种函数,实现类中某个属性的比较)。Lambda表达式需要使用委托定义。事件需要使用到委托。

      1.2、Lambda表达式与委托直接相关。Lambda表达式可以理解成一个简单的方法定义(包含参数、返回值),表达式由委托来指向。

      ——Lambda表达式的作用,减少代码量。

      1.3、事件,基于委托,为委托提供了一种发布/订阅机制。最直接的就是Button的Click事件。

    2.代码展示

      2.1、委托

      2.1.1:如何定义一个委托:

      1、这是需要进行委托的函数

    public static double MultiplyByTwo(double value)
            {
                return value * 2;
            }
    
            public static double Square(double value)
            {
                return value * value;
            }
    

      2、然后定义一个委托DoubleOp

           delegate double DoubleOp(double x);
                DoubleOp[] operations =
                {
                   MathOperations.MultiplyByTwo,
                   MathOperations.Square
                };

      3、调用委托

                Console.WriteLine(operations[0](2));
                Console.WriteLine(operations[1](2));

      4、返回结果

      2.1.2:Action<T>委托和Func<T>委托

      Action为返回值void的委托,Func为带返回类型(最后一个参数为返回类型)。

      如A中的第2步,可以改写做:

                Func<double, double>[] operations2 =
                {
                   MathOperations.MultiplyByTwo,
                   MathOperations.Square
                };

      委托更多的用处是作为函数的参数,可以把符合一定要求(参数、返回值一致)的函数作为参数传入其他函数(是不是很类似指针?)。

      如C#高级编程中的冒泡排序法:

            //Func的参数是动态的,根据实际添加的个数决定。
            static public void Sort<T>(IList<T> sortArray, Func<T, T, bool> comparison)
            {
                bool swapped = true;
                do
                {
                    swapped = false;
                    for (int i = 0; i < sortArray.Count - 1; i++)
                    {
                        if (comparison(sortArray[i+1], sortArray[i]))
                        {
                            T temp = sortArray[i];
                            sortArray[i] = sortArray[i + 1];
                            sortArray[i + 1] = temp;
                            swapped = true;
                        }
                    }
                } while (swapped);
            }

      其中一个参数为Func<T,T,bool> comparison。Sort<T>为泛型函数,可以对不同类型T的对象进行排序,而排序方法使用委托comparison。这样使用委托的改动,可以提高Sort函数的适用性,如范例中需要根据员工工资来进行排序,只需要传入一个根据类型Employee来比较员工工资的comparison即可。

      以下为调用的范例:

                Employee[] employees =
                {
                    new Employee("Bugs Bunny", 20000),
                    new Employee("Elmer Fudd", 10000),
                    new Employee("Daffy Duck", 25000),
                    new Employee("Wile Coyote", 1000000.38m),
                    new Employee("Foghorn Leghorn", 23000),
                    new Employee("RoadRunner", 50000)
                };
    
                BubbleSorter.Sort(employees, Employee.CompareSalary);

      

      比较员工工资的comparison——即Employee.CompareSalary是这么写的:

            public static bool CompareSalary(Employee e1, Employee e2)
            {
                return e1.Salary < e2.Salary;
            }

       2.2、Lambda表达式

      简单的定义函数的方式。

                string mid = ",2,";
                //有花括号(多条语句的情况)的需要return语句
                Func<string, string> lambdaTest = param =>
                {
                    param += mid;
                    param += "3";
                    return param;
                };
                Console.WriteLine(lambdaTest("1"));
    
                //没有花括号的会隐式添加一条return语句
                Func<string, string> oneParam = s => String.Format("change uppercase {0}", s.ToUpper());
                Console.WriteLine(oneParam("test"));
    
                Func<double, double, double> twoParams = (x, y) => x * y;
                Console.WriteLine(twoParams(3, 2));
    
                Func<double, double, double> twoParamsWithTypes = (double x, double y) => x * y;
                Console.WriteLine(twoParamsWithTypes(4, 2));
    
                Func<double, double> operations = x => x * 2;
                operations += x => x * x;
    
                ProcessAndDisplayNumber(operations, 2.0);

     

  • 相关阅读:
    1. shiro-用户认证
    Salt 盐值
    使用ajax向后台发送请求跳转页面无效的原因
    @RequestParam和@RequestBody的区别
    JavaSE:Java11的新特性
    JavaSE: Java10的新特性
    JavaSE:Java9 新特性
    JavaSE:Java8新特性
    JavaSE:Java8新特性
    JavaSE:Java8 新特性
  • 原文地址:https://www.cnblogs.com/Ebony-Ivory/p/4291967.html
Copyright © 2011-2022 走看看