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、返回结果

C# 委托、Lambda表达式和事件——学习总结

  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);

 

 

 

C# 委托、Lambda表达式和事件——学习总结

上一篇:012、多个fixture的使用顺序


下一篇:Windows 上安装 Jekyll.