LinqAndLambda

6 篇文章 0 订阅

program.cs

using System;

namespace LambdaAndLinq
{
    class Program
    {
        static void Main(string[] args)
        {
            Lambda.Show_();
            //Lambda是什么? 是实例化委托时传入的参数,是一个匿名方法
            //但是编译时会产生一个私有sealed类,给方法分配一个名字,放入这个给类中
            Console.WriteLine("Hello World!");
            C c = new C();
            c.Name = "";
            Linq.call();
            Linq.call_0();
        }
    }

    public class A
    {
        public virtual string Name { set; get; }
        public virtual void DoNothing()
        {
            Console.WriteLine("A DoNothing");
        }
    }
    public class B : A
    {
        public sealed override string Name { set; get; }
        public sealed override void DoNothing()
        {
            base.DoNothing();
        }
    }

    public class C : B
    {
        //因为B中密封,所以不能重写
        //public override string Name { set; get; }
    }
}

Lambda.cs

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

namespace LambdaAndLinq
{
    //委托可以定义在类外面
    public delegate void NoReturnNoPara_();
    public delegate void NoReturnIntPara_(int i);

    public class Lambda
    {
        #region Lambda发展历史
        public delegate void NoReturnNoPara();
        public delegate void NoReturnIntPara(int i);
        //Lambda是什么? 是实例化委托时传入的参数,是一个匿名方法
        //但是编译时会产生一个私有sealed类,给方法分配一个名字,放入这个给类中
        //sealed关键字复习:1,修饰类时,任何类不能继承被修饰的类。2,修饰属性方法时,继承父类虚方法或虚属性后,防止被子类重写
        //多播委托中如果直接传入Lambda,虽然方法体一样,但是时不同的的方法
        public void Show()
        {
            //Lambda演变史
            {
                //.NetFramework 1.0
                NoReturnNoPara NoReturnIntPara = new NoReturnNoPara(DoNothing);
                NoReturnIntPara.Invoke();
                NoReturnIntPara noReturnNoPara = new NoReturnIntPara(DoWithPara);
                noReturnNoPara.Invoke(123);
            }
            {
                //.NetFramework 2.0  方法名换成delegate关键字-->匿名方法
                NoReturnNoPara NoReturnIntPara = new NoReturnNoPara(delegate { Console.WriteLine("This is DoNothing"); });
                //相比1.0,可以给方法体中传入额外的变量,比如这个j
                int j = 9;
                NoReturnIntPara noReturnNoPara = new NoReturnIntPara(delegate (int i) { Console.WriteLine($"i is {i},j is {j}"); });
            }
            {
                //.NetFramework 3.0   delegate 关键字省略,增加=> goes to
                //lambda表达式
                NoReturnIntPara noReturnNoPara = new NoReturnIntPara((int i) => { Console.WriteLine($"i is {i}"); });
            }
            {
                //参数类型省略
                //方法体如果只有一句话,方法大括号和结尾分号也可以省略
                //委托 new可以省略
                NoReturnIntPara noReturnNoPara = (int i) => Console.WriteLine($"i is {i}");
                //带返回值的委托,只有一行可以省略return关键字
                Func<int> func = () => 2;
            }
        }
        private void DoNothing()
        {
            Console.WriteLine("This is DoNothing");
        }
        private void DoWithPara(int i)
        {
            Console.WriteLine($"i is {i}");
        }
        #endregion

        #region 3.0出现匿名类  匿名类中的属性是只读的
        public static void Show_()
        {
            //3.0   object定义的匿名类,无法访问其中的元素
            object student = new { age = 10, Name = "小高" };

            //4.0  dynamic 动态类型,避开编译器检查,但不安全
            dynamic student0 = new { age = 10, Name = "小高" };
            //student0.age = 10; //虽然可以写,但运行时报错,因为age只读

            //var 语法糖  它定义的类中属性时只读的
            var student1 = new
            {
                age = 10,
                Name = "小高",
            };
            //student1.age = 10; //不能写,报错,因为age只读

        }
        #endregion

        #region 3.0出现扩展方法
        //扩展方法必须定义在非泛型静态类中,也不能定义在嵌套类中
        //扩展方法,像实例方法一样使用
        //用处1,第三方类,不适合修改源码(但是实例方法有可能和扩展方法同名,此时以实例方法为准)
        //用处2,适合组件式开发的扩展(core中);定义接口或者类,是按照最小需求,但是在开发中又经常需要一些方法,就定义成扩展方法,比如context.Response.WriteAsync、中间件注册等
        //注意:不要为object和没有约束的泛型定义扩展,会造成污染
        public void Show1()
        {
            AA a = new AA();
            a.Show();
            a.ExtendShow();
        }
        #endregion
    }

    public class AA
    {
        public void Show()
        {
            Console.WriteLine("AA_Show");
        }
    }
    //扩展方法必须定义在非泛型静态类中,也不能定义在嵌套类中
    public static class ExtendAA
    {
        public static void ExtendShow(this AA aA)
        {
            Console.WriteLine("ExtendAA_Show");
        }
    }

}

Linq.cs

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

namespace LambdaAndLinq
{
    public class Linq
    {
        #region 迭代器模式
        //扩展方法的好处,陈述式语法
        //迭代器模式 Iterator
        //lambda用来实例化委托,是个方法
        //linq是个类库,依靠泛型,lambda,委托等实现
        public static void call()
        {
            var rst = new List<Student>();
            rst.Add(new Student { Name = "大王", Age = 19 });
            rst.Add(new Student { Name = "小高", Age = 16 });
            rst.Add(new Student { Name = "小王", Age = 17 });
            rst.Add(new Student { Name = "小高1", Age = 18 });
            rst.Add(new Student { Name = "小高2", Age = 18 });
            {
                var sss = rst.WhereNew(s => s.Name == "小王" || s.Age >= 18);
                foreach (var item in sss)
                {
                    Console.WriteLine(item.Name);
                }
            }
            {
                //迭代器模式,循环sss时才进入WhereNewIterator方法,并且找到满足的第一个就返回,下次进来接着上次迭代循环的地方继续,延迟加载
                //如果.ToList了,那么迭代器会一次执行完
                var sss = rst.WhereNewIterator(s => s.Name == "小王" || s.Age >= 18);
                var sss0 = rst.WhereNewIterator(s => s.Name == "小王" || s.Age >= 18).ToList();
                foreach (var item in sss)
                {
                    Console.WriteLine(item.Name);
                }
            }
        }
        #endregion

        #region Linq to Object 和 Linq to SQL
        public static void call_0()
        {
            #region Linq to Object  在Enumerable类,针对IEnumerable数据,指的是内存数据
            //linq:把对数据的通用操作完成,可变的逻辑交给委托 的这么一种封装
            //where:把对数据的通用操作完成,可变的过滤逻辑交给委托
            //select:把对数据的通用操作完成,可变的转换筛选逻辑交给委托
            List<Student> students = new List<Student>();
            students.Add(new Student { Name = "大王", Age = 19, Id = 1 });
            students.Add(new Student { Name = "小高", Age = 16, Id = 3 });
            students.Add(new Student { Name = "小王", Age = 17, Id = 5 });
            students.Add(new Student { Name = "小高1", Age = 18, Id = 4 });
            students.Add(new Student { Name = "小高2", Age = 18, Id = 6 });
            var rst = students.Where(item => item.Age >= 16)
                .Select(stu => new
                {
                    name = stu.Name,
                    age = stu.Age,
                    id = stu.Id
                }).OrderBy(stu => stu.age)
                //.OrderBy(t=>t.id)
                .ThenBy(t => t.id)
                .Skip(2)
                .Take(3)
                .ToList();

            var rst1 = students.GroupBy(t => t.Age).Select(ts => new
            {
                age = ts.Key,
                name = string.Join(',', ts.Select(t => t.Name)),
                id = ts.Select(t => t.Id).Sum()
            });
            #endregion

            #region Linq to SQL  在Queryable类,针对IQueryable数据,操作数据库
            //程序操作数据库,需要Ado.net+Sql
            //封装了通用数据库操作,可变的是SQL,SQL通过表达目录树来传递,这个是可以解析的
            var Questudents = students.AsQueryable();
            var rst2 = Questudents.Where(t => t.Age > 17);
            {
                //Linq to Object 传入委托,可以写任意方法体
                //Linq to SQL 传入的是需要解析成SQL的表达是目录树,虽然写法和Linq to Object 类似,但是需要受限制
                var rst3 = students.Where(t =>
                {
                    Console.WriteLine("-------");
                    return t.Age > 17;
                });
                //需要传入的表达式目录树能解析成SQL,所以不能这么写
                //var rst4 = Questudents.Where(t =>
                //{
                //    Console.WriteLine("-------");
                //    return t.Age > 17;
                //});
            }
            #endregion

            #region Linq to XML
            #endregion
        }
        #endregion
    }

    public class Student
    {
        public string Name { set; get; }
        public int Age { set; get; }
        public int Id { set; get; }
    }

    //以linq的方式给List类型加上自定义扩展方法
    public static class LinqMyExtend
    {
        public static List<T> WhereNew<T>(this List<T> students, Func<T, bool> func)
        {
            var rst = new List<T>();
            foreach (var item in students)
            {
                Console.WriteLine("正在检查");
                if (func.Invoke(item))
                    rst.Add(item);
            }
            return rst;
        }
        //迭代器模式,延迟加载
        public static IEnumerable<T> WhereNewIterator<T>(this List<T> students, Func<T, bool> func)
        {
            var rst = new List<T>();
            foreach (var item in students)
            {
                Console.WriteLine("正在检查");
                if (func.Invoke(item))
                    yield return item;      //yield配合IEnumerable使用
            }
        }
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值