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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值