Lambda表达式和闭包

一、Lambda表达式

1.描述
      Lambda表达式由一个左部(表示输入参数)、=>符号以及一个右部(表示需要求值的表达式)组成。
【示例】
using System;
namespace 简单的Lambda表达式
{
    class Program
    {
        //Lambda表达式省略了delegate关键字、函数头、参数类型、方括号以及return关键字
        //Lambda表达式就是一个简洁的委托。左侧(相对于运算符“=>”而言)代表函数的参数,而右侧是函数主体
        delegate void FunctionPointer(string str);
        static void Main(string[] args)
        {
            FunctionPointer fp =
                s => Console.WriteLine(s);

            fp("Hello World");
            Console.ReadLine();
        }
    }
}

2.搜索字符串

     泛型委托Predicate接受一个由T指定的参数并返回一个布尔值。Predicate用在诸如Array.Find和Array.FindAll这样的函数中。Predicate可以通过普通函数、匿名委托或是Lambda表达式来初始化。
【示例】
 using System;
using System.Linq;

namespace 搜索字符串
{
    class Program
    {
        static void Main(string[] args)
        {
            //通过匿名类型和数组初始化器创建一个people数组
            var people = new[]
            {
                "xu shuai","zhu xiao",
                "wang feng","xu tao",
                "hu xiang","bian jingbin","wang rui"
            };
            //Lambda表达式
            //Where:基于谓词筛选值序列
            var results = people.Where(
                s => s.Contains("xu"));
            Console.WriteLine("/*显示含有某个关键字的字符串*/");
            Array.ForEach<string>(results.ToArray<string>(), s => Console.WriteLine(s));
            //Predicate:泛型委托,用于定义一组条件并确定参数是否符合这些条件。
            Predicate<string> match = s => s.Contains("g");
            var ss = people.ToList<string>().FindAll(match);
            Console.WriteLine("/*使用list<T>的FindAll以及由Lambda表达式初始化的Predicate*/");
            Array.ForEach<string>(ss.ToArray<string>(), s => Console.WriteLine(s));
            Console.ReadKey();
        }
    }
}

3.从序列中获取特定元素
using System;
using System.Linq;

namespace 从序列中获取特定元素
{
    class Program
    {
        static void Main(string[] args)
        {
            var numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            //first
            var first = (from n in numbers select n).First();
            Console.WriteLine("数组的第一个数:{0}", first);
            var firstOrDefault = (from n in numbers select n).FirstOrDefault(n => n > 3);
            var firstOrDefault1 = (from n in numbers select n).FirstOrDefault(n => n > 10);
            Console.WriteLine("First or Default: {0}", firstOrDefault);
            Console.WriteLine("First or Default: {0}", firstOrDefault1);

            //single
            var single = (from n in numbers where n == 2 select n).Single();
            Console.WriteLine("Single: {0}", single);
            var singleOrDefault = (from n in numbers select n).SingleOrDefault(n => n == 2);
            Console.WriteLine("Single or Default: {0}", singleOrDefault);

            var singleOrDefault1 = (from n in numbers select n).SingleOrDefault(n => n == 20);
            Console.WriteLine("Single or Default: {0}", singleOrDefault1);

            //elment at
            var element = (from n in numbers select n).ElementAt(2);
            Console.WriteLine("elementat: {0}", element);

            var elementOrDefault = (from n in numbers select n).ElementAtOrDefault(11);
            Console.WriteLine("Element at 11 or default: {0}", elementOrDefault);

            var elementOrDefault1 = (from n in numbers select n).ElementAtOrDefault(8);
            Console.WriteLine("Element at 11 or default: {0}", elementOrDefault1);

            Console.ReadKey();
        }
    }
}

4.筛选信息
using System;
using System.Linq;

namespace 筛选信息
{
    class Program
    {
        static void Main(string[] args)
        {
            var numbers = new int[] { 32, -2, 3, 43, 6, 14, -24, 8, 0 };
            var result = from n in numbers where Math.Abs(n) > 20 select n;
            foreach (var item in result)
            {
                Console.WriteLine(item);
            }
            var randomDate = new object[] { 1, 2, "two", "three", 5, "monday",34m };
            var beInt = from i in randomDate.OfType<int>() select i;
            var beString = from s in randomDate.OfType<string>() select s;
            var beDecimal = from d in randomDate.OfType<decimal>() select d;
            Console.WriteLine("整型数字:");
            foreach (var item in beInt)
            {
                Console.WriteLine(item);
            }
            Console.WriteLine("字符串:");
            foreach (var item in beString)
            {
                Console.WriteLine(item);
            }
            Console.WriteLine("deciaml类型:");
            foreach (var item in beDecimal)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
        }
    }
}

5.使用Select和Lambda表达式
【示例】
using System;
using System.Linq;

namespace 使用Select和Lambda表达式
{
    class Program
    {
        static void Main(string[] args)
        {
            var numbers = new int[] { 1, 3, 4, 54, 2, 32 };
            //select返回的是一个IEnumerable<T>实例,其中T是Lambda表达式所返回的对象的类型
            foreach (var item in numbers.Select(n=>n%2))
            {
                Console.WriteLine(item);
            }
            //通过命名初始化的方式将n投影为一个新的类型
            foreach (var item in numbers.Select(n=>new {Number=n,isEven=n%2==0 }))
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
        }
    }
}

6.使用Where和Lambda表达式
using System;
using System.Collections.Generic;
using System.Linq;

namespace 使用Where和Lambda表达式
{
    class Program
    {
        static void Main(string[] args)
        {
            var words = new string[] { "xushuai", "hahh", "xianggou", "jijisa" };
            IEnumerable<string> hasX = words.Where(s => s.Contains("x"));
            foreach (var item in hasX)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
        }
    }
}

7.使用OrderBy和Lambda表达式
【示例】
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 使用OrderBy和Lambda表达式
{
    class Program
    {
        static void Main(string[] args)
        {
            var numbers = new int[] { 32, 43, 3, 2, 53, 47 };
            Console.WriteLine("/*升序排序*/");
            IEnumerable<int> orderDesc = numbers.OrderBy(n => n);
            foreach (var item in orderDesc)
            {
                Console.WriteLine(item);
            }
            Console.WriteLine("/*降序排序*/");
            IEnumerable<int> orderAsc = numbers.OrderByDescending(n => n);
            foreach (var item in orderAsc)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
        }
    }
}

8.Lambda表达式和闭包
      由于变量存在生命周期,换句话说,变量的作用域是有范围的。例如,当我们在一个函数中声明一个变量后,在函数执行完毕后,这个变量将从该函数的栈内存空间中清除掉。试想,如果我们在一个Lambda表达式中使用了本地变量的话,该本地变量将会在函数的栈空间清理的时候被移除。为了防止这样的糟心事发生,当一个依赖于本地变量的Lambda表达式需要从函数中返回出去,编译器就会创建一个闭包,即一个包装器类。
      闭包是一个自动生成的类,它含有Lambda表达式,并为每个被用到的本地变量生成一个字段。这些本地变量的值会被复制到相应的字段中,以便扩展这些本地变量的生命周期。
【示例】
using System;
using System.Collections.Generic;
using System.Linq;

namespace Lambda表达式和闭包
{
    class Program
    {
        static void Main(string[] args)
        {
            UserClosur();
            Console.ReadKey();
        }
        static void UserClosur()
        {
            string toFind = "ed";
            var words = new string[]
            {
                "ended","experienced",
                "friend","closed","hahah"
            };
            //使用本地变量toFind就会通知编译器生成一个闭包(或包装器类)
            //这样,toFind就不会称为“未定义”的
            var matches = words.Select(s => s.Contains(toFind));
            foreach (var item in matches)
            {
                Console.WriteLine(item);
            }
            IEnumerable<string> hasED = words.Where(s => s.Contains("ed"));
            foreach(string s in hasED)
            {
                Console.WriteLine(s);
            }
        }
    }
}

三、柯里化
         即将一个多步骤表达式拆分成多个Lambda表达式,每一个Lambda表达式都是下一个Lambda表达式的资源提供者,最后一个表达式所提供的就是整个解决方案
【示例】
using System;

namespace 柯里化
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<int, int, int> test1 = (x, y) => x + y;
            Console.WriteLine(test1(4, 7));//11
            Func<int, Func<int,int>> test2 = x => y => x + y;
            Console.WriteLine(test2(4)(7));//11
            Console.ReadKey();
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值