C# 委托-->Lambda-->LINQ详解

一. 简介

委托(Delegate)是一种引用类型,可以看作是函数指针,用来封装一个或多个方法,并允许将这些方法作为参数传递给其他方法。委托可以用于实现事件和回调机制,提供了一种灵活的方式来处理方法的组合和调用。

最直观的理解就是把定义的委托类型当成是一个变量,使用一个方法给这个委托类型的变量赋值。

LINQ(Language Integrated Query)是C#语言中的一个查询语言扩展,用于方便地进行数据查询和操作。LINQ 可以对不同类型的数据源进行查询,包括集合(List、Array等)、数据库、XML等。它提供了一种统一的语法和操作符,使得我们可以使用类似 SQL 的语句来过滤、排序、分组和投影数据。

二. 原始的委托使用

声明委托类型-->声明委托变量-->给委托对象赋值-->使用委托

namespace 委托_Lambda_LINQ
{
    // 声明4种委托类型,分别为:
    // 无参无返回值
    public delegate void AddDle1();

    // 有参无返回值
    public delegate void AddDle2(int i);

    // 无参有返回值
    public delegate int AddDle3();

    // 有参有返回值
    public delegate int AddDle4(int i);
    internal class Program
    {
        static void Main(string[] args)
        {
            //分别声明这四种委托类型变量,并赋值
            AddDle1 addDle1 = Add1;
            AddDle2 addDle2 = Add2;
            AddDle3 addDle3 = Add3;
            AddDle4 addDle4 = Add4;


            // 分别执行调用这几个委托,两种调用方式效果是一样的
            addDle1.Invoke();
            addDle2.Invoke(1);

            int a = addDle3();
            int b = addDle4(1);
        }

        public static void Add1()
        { 
        
        }
        public static void Add2(int i)
        {
            int a = i;
        }
        public static int Add3()
        {
            return 0;
        }
        public static int Add4(int i)
        {
            return i + 10;
        }
    }
}

三. 委托简化 Action和Func的使用

微软为了简化委托的声明,直接内置了一个无返回值的Action泛型委托类型,和有返回值的Func泛型委托类型。

使用委托时就可以直接定义成Action或Func类型,不需要提前声明委托类型了。

namespace 委托_Lambda_LINQ
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Action addDle1 = Add1;
            Action<int> addDle2 = Add2;
            Func<int> addDle3 = Add3;
            Func<int, int> addDle4 = Add4;

            // 分别执行调用这几个委托,两种调用方式效果是一样的
            addDle1.Invoke();
            addDle2.Invoke(1);

            int a = addDle3();
            int b = addDle4(1);
        }

        public static void Add1()
        { 
        
        }
        public static void Add2(int i)
        {
            int a = i;
        }
        public static int Add3()
        {
            return 0;
        }
        public static int Add4(int i)
        {
            return i + 10;
        }
    }
}

四. 委托赋值使用匿名方法

namespace 委托_Lambda_LINQ
{
    internal class Program
    {

        static void Main(string[] args)
        {
            Action addDle1 = delegate () 
            { 
                Console.WriteLine("我是匿名方法Add1"); 
            };

            Action<int> addDle2 = delegate (int i) 
            { 
                Console.WriteLine("我是匿名方法Add1"); 
            };

            Func<int> addDle3 = delegate () 
            { 
                Console.WriteLine("我是匿名方法Add3"); 
                return 0;
            };

            Func<int, int> addDle4 = delegate (int i) 
            { 
                Console.WriteLine("我是匿名方法Add4");
                return i + 10;
            };

            // 分别执行调用这几个委托,两种调用方式效果是一样的
            addDle1.Invoke();
            addDle2.Invoke(1);

            int a = addDle3();
            int b = addDle4(1);
        }

        //public static void Add1()
        //{
        //    Console.WriteLine("我是常规方法Add1");
        //}
        //public static void Add2(int i)
        //{
        //    int a = i;
        //    Console.WriteLine("我是常规方法Add2");
        //}
        //public static int Add3()
        //{
        //    Console.WriteLine("我是常规方法Add3");
        //    return 0;
        //}
        //public static int Add4(int i)
        //{
        //    Console.WriteLine("我是常规方法Add4");
        //    return i + 10;
        //}
    }
}

五. Lambda表达式

5.1 由匿名方法过度到使用=>, 省略delegate关键字,参数类型和括号

namespace 委托_Lambda_LINQ
{
    internal class Program
    {

        static void Main(string[] args)
        {
            Action addDle1 = () =>
            {
                Console.WriteLine("我是匿名方法Add1");
            };

            Action<int> addDle2 = (i) =>
            { 
                Console.WriteLine("我是匿名方法Add1"); 
            };

            Func<int> addDle3 = () =>
            { 
                Console.WriteLine("我是匿名方法Add3"); 
                return 0;
            };

            Func<int, int> addDle4 = (i) =>
            { 
                Console.WriteLine("我是匿名方法Add4");
                return i + 10;
            };

            // 分别执行调用这几个委托,两种调用方式效果是一样的
            addDle1.Invoke();
            addDle2.Invoke(1);

            int a = addDle3();
            int b = addDle4(1);
        }
    }
}

5.2 如果方法内只有一行代码,可以省略大括号和return

namespace 委托_Lambda_LINQ
{
    internal class Program
    {

        static void Main(string[] args)
        {
            Action addDle1 = () => Console.WriteLine("我是匿名方法Add1");

            Action<int> addDle2 = i => Console.WriteLine("我是匿名方法Add1"); 
            
            Func<int> addDle3 = () => 0;

            Func<int, int> addDle4 = i => i + 10;

            // 分别执行调用这几个委托,两种调用方式效果是一样的
            addDle1.Invoke();
            addDle2.Invoke(1);

            int a = addDle3();
            int b = addDle4(1);
        }
    }
}

六. LINQ语句中的委托

namespace 委托_Lambda_LINQ
{
    internal class Program
    {

        static void Main(string[] args)
        {
            List<int> list = new List<int>() {1,2,3,4,5,6,7 };

            // 常规的Linq语句,实际上Where的参数就是一个Func委托
            list = list.Where(p=> p < 5).ToList();

            //将这个参数的Func委托进行还原
            Func<int, bool> func = p => p < 5;
            list = list.Where(func).ToList();

            //继续还原
            Func<int, bool> func1 = (p) => { return p < 5; };
            list = list.Where(func1).ToList();

            //继续还原
            Func<int, bool> func2= delegate (int p) { return p < 5; };
            list = list.Where(func2).ToList();

             //继续还原
             Func<int, bool> func3 = Select;
             list = list.Where(func3).ToList();

             //继续还原
             Func<int, bool> func4 = Select;
             list = MyWhere(list, func4).ToList();

             //继续还原
             list = MyWhere(list);
        }

        public static List<int> MyWhere(List<int> ints, Func<int, bool> func4)
        {
            var list = new List<int>();
            foreach (int i in ints) 
            {
                if (func4.Invoke(i))
                {
                    list.Add(i);
                }
            }
            return list;
        }
        public static List<int> MyWhere(List<int> ints)
        {
            var list = new List<int>();
            foreach (int i in ints)
            {
                if (Select(i))
                {
                    list.Add(i);
                }
            }
            return list;
        }

        public static bool Select(int p)
        {
            return p < 5;
        }
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Lambda表达式->,是Java 8中引入的一种函数式编程的特性。它可以简洁地表示一个匿名函数,可以作为参数传递给方法或函数。Lambda表达式的结构可以根据需要有零个或多个参数,参数可以明确声明或根据上下文推断。参数需包含在圆括号内,参数之间用逗号相隔。当只有一个参数且其类型可推导时,圆括号可以省略。Lambda表达式的主体可以包含零条或多条语句,如果主体只有一条语句,花括号{}可以省略。Lambda表达式的返回类型与主体表达式一致。如果主体包含一条以上的语句,表达式必须包含在花括号{}中形成代码块,返回类型与代码块的返回类型一致。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Lambda 表达式](https://blog.csdn.net/xxdw1992/article/details/103903210)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [深入浅出 Java 8 Lambda 表达式](https://blog.csdn.net/u012910595/article/details/70833510)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值