匿名委托Func—Action; 朗姆达表达式

委托定义了一种引用类型,表示对具有特定参数列表和返回类型的方法的引用。 其参数列表和返回类型匹配的方法(静态或实例)分配给该类型的变量,然后(使用适当参数)直接调用该方法,或将其作为参数本身传递给另一方法再进行调用

为简化开发过程,.NET 包含一组委托类型,程序员可重用这些类型而无需创建新类型。

这些类型是 Func<>Action<> 和 Predicate<>,可以使用它们而无需定义新的委托类型。

但是,即使使用此方法,仍有许多可以丢弃的代码。 此时就需要使用 lambda 表达式

Lambda 表达式是指定委托的另一种方式

原始委托的申明及使用:

using System;

namespace ConsoleApp3
{
    internal class Program
    {
        //委托的本质是一个密封类,它的父类是:MulticastDelegate
        //委托说白了就是一个数据类型,就像string 类型接收字符串数据 int类型接收整形数据, 而委托类型接收方法

        //定义一个返回值为Int 带两个参数的委托
        public delegate int SumDelegate(int x, int y);
        static void Main(string[] args)
        {
            Type type = typeof(SumDelegate);
            Console.WriteLine(type.IsClass);
            Console.WriteLine(type.BaseType.Name); //查看委托的父类名称:MulticastDelegate ;MulticastDelegate是一个抽象类
            Console.WriteLine(type.BaseType.BaseType.Name); //查看委托的父类的父类名称:Delegate ; Delegate是一个abstract抽象类


            //委托的使用


            //第一种用法:指定方法
            SumDelegate sumdel = new SumDelegate(SumFun);
            var sumA = sumdel.Invoke(1, 2);  //通过Invoke来调用:sum的值是3
            var sumB = sumdel(1, 2);          //也可以直接调用:sum的值是3

            //第二种用法:匿名委托
            SumDelegate sumdel1 = delegate (int a, int b) { return a + b; };
            var sum1A = sumdel1.Invoke(2, 3); //通过Invoke来调用:sum1A的值是5
            var sum1B = sumdel1(2, 3);        //也可以直接调用:sum1B的值是5


            //第三种用法:直接赋值一个方法:这是第一种的简化版
            SumDelegate sumdel2 = SumFun;
            var sum2A = sumdel2.Invoke(3, 4); //通过Invoke来调用:sum2A的值是7
            var sum2B = sumdel2(3, 4);       //也可以直接调用:sum2B的值是3

            //第四种用法:朗姆达表达式:这是第二种的简化版
            SumDelegate sumdel3 = (a, b) => a + b;
            var sum3A = sumdel3.Invoke(3, 4);
            var sum3B = sumdel3(3, 4);


            //使用委托的案列:求数组的最大值


            string[] strArr = { "abc", "EDdee", "edd", "DEFrr" };
            int[] intArr = { 2, 8, 9, 63, 12, 3 };
            var strArrMaxValue = GetArrMaxValue(strArr, (x, y) =>
            {
                var dvalue = string.Compare(x, y, false); //第三个参数ignoreCase:表示是否区分大小写; true表示不区分大小写,false表示区分大小写。
                return dvalue < 0;
            });
            var intArrMaxValue = GetArrMaxValue(intArr, (x, y) => { return x - y < 0; });

        }

        private static int SumFun(int a, int b)
        {
            return a + b;
        }


        private static T GetArrMaxValue<T>(T[] arr, Func<T, T, bool> func)
        {
            T max = arr[0];
            for (int i = 0; i < arr.Length; i++)
            {
                var booVal = func(max, arr[i]);
                if (booVal)
                {
                    max = arr[i];
                }
            }
            return max;
        }
    }
}

匿名委托,也称作匿名方法

namespace ConsoleTest
{
    public delegate void Mydeleage(int x, int y);//定义了一个委托
    class Program
    {
        static void Main(string[] args)
        {
            //这里定义了一个匿名委托:delegate(int x, int y){ Console.WriteLine(x + y); };
            //定义的这个匿名委托需要有一个相对应的委托变量去指向它。【匿名委托也叫匿名方法】
            Mydeleage del = delegate(int x, int y)
               {
                   Console.WriteLine(x + y);
               };
        }
    }
}

Action 与 Func委托

Action和 Func是.NET中已经声明好的两种委托 ,一种没有返回值,一种可以有返回值

Action:表示无返回值的委托

Func  :表示带返回值的委托

申明Action 与 Func委托案例:

//-------------------------------无返回值的委托Action-----------------------------------

//无返回值,无参数的委托,相当于public delegate void action(),
Action action 

//无返回值,带一个string类型参数的委托,相当于public delegate void action(string str); 
Action<string> action  


//-----------------------------有返回值的委托Func----------------------------------------

//返回值为int,带一个string类型参数的委托:注意最后一个参数为返回值;
//它相当于public delegate int func(string str);
Func<string,int> func 


//返回值为int,无参数的委托:它相当于public delegate int func();
Func<int> func; 

利用委托对List进行扩展一个Where方法 案例:

using System;
using System.Collections.Generic;

namespace ConsoleApp3
{
    public static class ExtenssionLinq
    {
        //自己封装一个Where数据刷选方法:它是一个对List的扩展
        public static List<T> MyWhere<T>(this List<T> list, Func<T, bool> func)
        {
            List<T> source = new List<T>();
            foreach (var item in list)
            {
                if (func(item))
                {
                    source.Add(item);
                }
            }
            return source;
        }
    }
}

Lambda表达式指定委托案列:

Lambda表达式是一种简洁而强大的编程语法,它可以用于创建匿名函数或委托。

通过Lambda表达式,我们可以轻松地编写内联的、即时执行的函数,无需额外定义命名函数或委托。

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

namespace 拉姆达表达式
{
    class Program
    {	//Action action是一个没有返回值,没有参数的委托,它相当于 public deletage void action()
        public void SayHello(Action action) 
        {
            action(); //执行这个委托
        }
        static void Main(string[] args)
        {
            Program p = new Program();
            p.SayHello( //这里是调用SayHello方法

                //实现委托,指定委托注册处理函数为Console.WriteLine()方法
                () => { Console.WriteLine(" 哈哈"); } //既然这个委托没有参数,就可以写成()=> { 表达式 }。

                );
            Console.ReadKey();
        }
    }
}

委托与Lambda表达式的关系:

lambda 表达式只是指定委托的另一种方式

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

namespace 朗姆达表达式
{
    //“Lambda 表达式”是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式树类型
    class Program
    {
        public delegate int del(int x);
        
        static void Main(string[] args)
        {
            del mydel = (x) =>   //如果拉姆的这有一个参数的时候可以简写,即:del mydel=x=>x*x;
            {
                return x * x;
            };

            int i = mydel(5);
            Console.WriteLine(i); //输出25

            //------------------------------------------只有一个int参数,返回值为int类型的委托

            Func<int, int> fun = x => x * x;
            int j = fun(6);
            Console.WriteLine(j); //输出36

            Func<int, int> fun2 = (x) => //这一句与上面的fun委托效果是一样的。只是这里是全写,上面是简写
            {
                return x * x;
            };
            int j2 = fun2(6);
            Console.WriteLine(j2); //输出36

            //------------------------------------------只有2个int参数,返回值为int类型的委托

            Func<int, int, int> fun3 = (x, y) => { return x * y; };
            int j3=fun3(5, 6);
            Console.WriteLine(j3); //输出30


            //这是一个有2个int参数,返回值为int的委托,相当于 public delegate int fun4(int a, int b);
            Func<int, int, int> fun4 = (int a,int b) =>
            {
                if (a > b)
                {
                    return a;
                }
                else
                {
                    return b;
                }
            };
            int j4 = fun4(8, 18);
            Console.WriteLine(j4);  //输出18


            //与上文使用delegate定义匿名方法的作用相同,Lambda表达式的作用也是为了定义一个匿名方法。因此,下面使用delegate的代码和上面是等价的:
            Func<int, int, int> fun5 = delegate(int a, int b)
            {
                if (a > b)
                {
                    return a;
                }
                else
                {
                    return b;
                }
            };
            int j5 = fun4(8, 18);
            Console.WriteLine(j5);  //输出18

            //那么您可能就会问,这样看来Lambda表达式又有什么意义呢?Lambda表达式的意义便是它可以写的非常简单,例如之前的Lambda表达式可以简写成这样:
            Func<int, int, int> max = (a, b) =>
            {
                if (a > b)
                {
                    return a;
                }
                else
                {
                    return b;
                }
            };
            int j6 = max(8, 18);
            Console.WriteLine(j6);  //输出18
                                        

            //-----------------------------------------只有一个参数,没有返回值的委托的朗姆达表达式

            Action<int> action = (x) =>
                {
                    Console.WriteLine(x * x);
                };
            action(8); //调用action委托。输出64


            Action<string> action3 = n => { string s = n + "你好"; Console.WriteLine(s); };
            action3("Hi"); //调用action3委托。输出 Hi你好


            //-----------------------------------------没有参数,没有返回值的委托的朗姆达表达式

            Action action2 = () => { Console.WriteLine("中国"); };
            action2(); //调用action2委托。输出 中国

            //他相当于:先定义一个委托,然后让委托指向Console类下面的WriteLine方法

            // public delegate void action2()  
            // action2 action22 = new Program.action2(Console.WriteLine);
           

            //-----------------------------------------------------------------------

            int[] oddNumbers = { 8, 3, 5, 9, 15, 1, 6 };

            //Count是返回一个数字,表示在指定的序列中满足条件的元素数量。
            int result = oddNumbers.Count((s) => { return s % 2 == 1; }); //求 oddNumbers数组中各个元素除2取余等于1的数字个数
                //oddNumbers.Where((r) => 
                //    {
                //        return r % 2 == 1;
                //    }).Count();

            Console.WriteLine(result); //输出5


            //FindAll是检索指定谓词定义的条件匹配的所有元素
            List<int> slist = new List<int> { 1, 4, 2, 7, 3 };
            var ss = slist.FindAll(d => d % 2 == 0);  //检索出slist数据集中除2等于0的所有元素
            foreach (var item in ss)
            {
                Console.WriteLine(item);  //输出4,2
            }

            Console.ReadKey();
        }
    }
}

朗姆达表达式:

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

namespace 朗姆达表达式2
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> strList = new List<string>() { "1", "8", "5", "16", "2", "25" };
            List<int> intList = new List<int>() { };
            List<int> eveList = new List<int>() { };
            List<int> squareList = new List<int>() { };

            foreach (var item in strList)// 将strList的元素都转成int类型的整数,然后给他添加到intList中
            {
                intList.Add(int.Parse(item));
            }




            foreach (var item in intList)// 找出元素中所有偶数,然后给它添加到eveList集合中
            {
                if (item % 2 == 0)
                {
                    eveList.Add(item);
                }
            }

            foreach (var item in eveList)  // 算出每个数的平方,然后给它添加到squareList集合中
            {
                squareList.Add(item * item);
            }

           
            squareList.Sort();// 按照元素自身排序

            foreach (var item in squareList)
            {
                Console.Write(item + " ");
            }



            //--------------------------------------------用朗姆达表达式实现


            var list= strList
                .Select(s => int.Parse(s)) // 将strList的元素都转成int类型的整数
                .Where(y => y % 2 == 0)  // 找出元素中所有偶数
                .OrderBy(z => z)  // 按照元素自身排序
                .Select(a => a * a)  // 算出每个数的平方
                .ToList();   //构造一个List

            foreach (var item in list)
            {
                Console.Write(item + " ");
            }
            Console.Read();
            
        }
    }
}

 扩展:对IEnumerable类进行扩展

namespace Demo
{
    static class JiHeExt
    {
        public static IEnumerable<T> MyWhere<T>(this IEnumerable<T> data, Func<T, bool> fun)
        {
            List<T> list = new List<T>();
            foreach (T item in data) //其实这个data就是int[] arr = { 1, 5, 3, 9, 20, 6, 78, 15 };这个数组
            {
                if (fun(item) == true)//判断遍历的这条数据是否满足条件fun
                {
                    list.Add(item);
                }
            }
            return list;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            int[] arr = { 1, 5, 3, 9, 20, 6, 78, 15 }; //int[]是实现了IEnumerable接口的
            var myarr = arr.MyWhere(i => i > 10); //的到:20,78,15
        }
    }
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值