c#委托与lambda表达式

委托

C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。
委托(Delegate)特别用于实现事件和回调方法。所有的委托(Delegate)都派生自 System.Delegate 类。

我们由例子引出委托:
实现返回最大值的功能

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

namespace Text1
{
    class Program
    {
        static int Max(List nums)
        {
            int max = nums[0];
            foreach (var num in nums)
            {
                if (max < num)
                {
                    max = num;
                }
            }
            return max;
        }
        static void Main(string[] args)
        {
            Console.WriteLine(Max(new List() { 1, 2, 3, 4, 5, 6 }));
            Console.ReadLine();
        }
    }
}

利用enum枚举类型和switch语句实现返回最大值或最小值

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

namespace Text1
{
    enum RetType
    {
        max,
        min,
    }
    class Program
    {
        static int Fun(List nums,RetType retType )
        {
            int max = nums[0];
            foreach (var num in nums)
            {
                switch (retType)
                {
                    case RetType.max:
                        if (max < num)
                        {
                            max = num;
                        }
                        break;
                    case RetType.min:
                        if (max > num)
                        {
                            max = num;
                        }
                        break;
                }
            }
            return max;
        }
        static void Main(string[] args)
        {
            Console.WriteLine(Fun(new List() { 1, 2, 3, 4, 5, 6 }, RetType.min));
            Console.ReadLine();
        }
    }
}

这个程序完美吗?当热不完美,因为面向对象编程一个重要思想是代码的封闭性,这个代码实现不了封闭。
看一下下面的这个例子,遍历List 挑选出>=10的元素

        static List Traverse(List nums)
        {
            var list = new List();
            foreach (var num in nums)
            {
                if (num > 10)
                {
                    list.Add(num);
                }
            }
            return list;
        }
       

如果让遍历List 挑选出偶数那 只需将num>10改为num%2==0即可,但是第一个例子一样,无法实现封装,
便引出了封装观察以下代码:只要声明一个函数就可以解决这个问题。

        static bool Function(int num)
        {
            return num > 10;
        }
        static List Traverse(List nums)
        {
            var list = new List();
            foreach (var num in nums)
            {
                if (Function(num))
                {
                    list.Add(num);
                }
            }
            return list;
        }

但是我们不希望是Traverse()调用函数Function()实现的,而是将Function()当成参数传进Traverse();
接下来,引入委托:
第一步:声明委托
第二步:修改形参列表
第三步:传入委托

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

namespace Text1
{

    class Program
    {
        delegate bool Function(int num);//声明委托,函数签名

        static Function GreaterThan10=delegate(int n){return n>10;};//引入委托  返回大于10的数
        static Function Iseven = delegate (int n) { return n % 2 == 0; };//引入委托 返回偶数

        static List Traverse(List nums,Function function )//修改形参列表
        {
            var list = new List();
            foreach (var num in nums)
            {
                if (function(num))
                {
                    list.Add(num);
                }
            }
            return list;
        }
       
        static void Main(string[] args)
        {
            Traverse(new List() { 0, 6, 20, 15, 32 }, GreaterThan10);
            Traverse(new List() { 0, 6, 20, 15, 32 }, Iseven);

            Console.WriteLine();
            Console.ReadLine();
        }
    }
}

lambda表达式

就是一种对委托的化解写法

语句 lambda: (type var,....)=>{} 多个参数
()=>{} 无参数
var=>{} 一个参数
表达式lambda: 没有{},但是只能有一条语句,和if语句相似

  static void Main(string[] args)
        {
            Traverse(new List() { 0, 6, 20, 15, 32 }, delegate (int n) { return n > 10; });
            Traverse(new List() { 0, 6, 20, 15, 32 }, (int n)=> { return n > 10; });
            Traverse(new List() { 0, 6, 20, 15, 32 }, (n) => { return n > 10; });
            Console.ReadLine();
        }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Text1
{

    class Program
    {
        delegate bool Function(int num);//声明委托,函数签名
        static List Traverse(List nums,Function function )//修改形参列表
        {
            var list = new List();
            foreach (var num in nums)
            {
                if (function(num))
                {
                    list.Add(num);
                }
            }
            return list;
        }
       
        static void Main(string[] args)
        {
            var list=Traverse(new List() { 0, 6, 20, 15, 32 }, (n) => { return n > 10; });
            foreach (var num in list)
            {
                Console.WriteLine(num);
            }
            Console.ReadLine();
        }
    }
}

泛型委托

delegate bool Function1(T num);

系统自带的一些泛型委托

Action<> 例 List.foreach
Func<> 例 List.Sum()
Predicate<> 例 List.Find()

Action<> 相当于无返回值的委托 Action action<>= delegate void Function1(T num);

 static void Main(string[] args)
        {
            var list = new List() { 0, 6, 20, 15, 32 };
            //foreach (var num in list)
            //{
            //    Console.WriteLine(num);
            //}
            list.ForEach(i => { Console.WriteLine(i); });
            Console.ReadLine();
        }

Func<> 相当于返回值的委托

      static void Main(string[] args)
        {
            var list = new List() { 0, 6, 20, 15, 32 };
            //list.Sum((n) => {if (n >= 10)return 0; else {return n; }});
            Console.WriteLine(list.Sum((n) => { if (n >= 10) return 0; else { return n; } }));
            Console.ReadLine();
        }

Predicate<> 相当于返回bool的委托

        static void Main(string[] args)
        {
            var list = new List() { 0, 6, 20, 15, 32 };
            list.FindAll((n) =>  n >= 10 );
            Console.WriteLine();
            Console.ReadLine();
        }
       

案例

泛型委托与lambda表达式结合使用

class Program
    {
        //delegate bool Function(int n);
        //static Function function = delegate (int n) { return n > 5; };
        //Func func = delegate (int n) { return n > 10; };
        static List Compare(List array, Func func)
        {
            List res = new List();
            foreach (var item in array)
            {
                if (func(item))
                {
                    res.Add(item);
                }
            }
            return res;
        }
        static void Main(string[] args)
        {
            var res= Compare(new List() { 1,2,3,4,5,6,7,8,9}, (n) => { return n > 6; });
            foreach (var item in res)
            {
                Console.WriteLine(item);
            }
            Console.ReadLine();
        }
    }

泛型委托实例

class Program
    {
        //delegate bool Function(int n);
        //static Function function = delegate (int n) { return n > 5; };
        static Func function = delegate (int n) { return n > 10; };
        static List Compare(List array, Func func)
        {
            List res = new List();
            foreach (var item in array)
            {
                if (func(item))
                {
                    res.Add(item);
                }
            }
            return res;
        }
        static void Main(string[] args)
        {
            var res= Compare(new List() { 1,2,3,4,5,6,7,8,9}, function);
            foreach (var item in res)
            {
                Console.WriteLine(item);
            }
            Console.ReadLine();
        }
    }

表达式树

表达式树核心概念就是:将代码作为数据。它将一些代码表示为一个对象树,树中的每个节点本身都是一个表达式,不同的表达式类型代表能在代码中执行不同操作:二元操作,一元操作,方法调用等等。

你可能感兴趣的:(c#委托与lambda表达式)