C# LINQ

语言集成查询 (LINQ) 是一系列直接将查询功能集成到 C# 语言的技术统称。

查询表达式(生成表达式)

 1、IEnumerable<T> 查询编译为委托。如 source.Where(m=>m.Id>1) 返回一个表达式,这个表达式可以转为委托。

2、 IQueryable 和 IQueryable<T> 查询编译为表达式树。

存储查询结果(计算表达式)

两个测试帮助理解 什么是生成表达式什么是计算表达式

    public static class ListTest
    {
        public static List<T1> Source { get; set; } = new List<T1>
            {
                new T1{ Id=1, Name="1" },
                new T1{ Id=2, Name="2" },
                new T1{ Id=3, Name="3" },
                new T1{ Id=4, Name="4" },
                new T1{ Id=5, Name="5" },
                new T1{ Id=6, Name="6" },
                new T1{ Id=7, Name="7" },
                new T1{ Id=8, Name="8" },
                new T1{ Id=9, Name="9" },
            };
        public static void Test()
        {
            //注意循环性能

            foreach (T1 item in Source)
            {
                if (item.Id <= 1)
                {
                    continue;
                }
                //do something
            }

            /**
            // loop start (head: IL_002c)
            IL_000f: ldloca.s 0
            IL_0011: call instance !0 valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<class IListTest.T1>::get_Current()
            IL_0016: stloc.1
            IL_0017: nop
            IL_0018: ldloc.1
            IL_0019: callvirt instance int32 IListTest.T1::get_Id()
            IL_001e: ldc.i4.1
            IL_001f: cgt
            IL_0021: ldc.i4.0
            IL_0022: ceq
            IL_0024: stloc.2
            IL_0025: ldloc.2
            IL_0026: brfalse.s IL_002b

            IL_0028: nop
            IL_0029: br.s IL_002c

            IL_002b: nop

            IL_002c: ldloca.s 0
            IL_002e: call instance bool valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<class IListTest.T1>::MoveNext()
            IL_0033: brtrue.s IL_000f
            // end loop
             */


            foreach (T1 item in Source.Where(m =>
            {
                return m.Id > 1;
            }))
            {
                //do something
            }

            /*
            // loop start (head: IL_0082)
            IL_0078: ldloc.3
            IL_0079: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1<class IListTest.T1>::get_Current()
            IL_007e: stloc.s 4
            IL_0080: nop
            IL_0081: nop

            IL_0082: ldloc.3
            IL_0083: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()
            IL_0088: brtrue.s IL_0078
            // end loop
             
             */

        }
    }
        private static string tag;
        private static void Main(string[] args)
        {

             tag = "s";
            //IEnumerable<T1> s = Init();//不同实例
            List<T1> s = Init().ToList();//同实例
            tag = "s2";
            IEnumerable<T1> s2 = s.ToList();
            if (ReferenceEquals(s.First(m => m.Id == 0), s2.First(m => m.Id == 0)))
            {
                System.Console.WriteLine("同实例");
            }
            else
            {
                System.Console.WriteLine("不同实例");
            }
            System.Console.ReadLine();
        }


        private static IEnumerable<T1> Init()
        {
            for (int i = 0 ; i < 100 ; i++)
            {
                System.Console.WriteLine(tag);
                yield return new T1 { Id = i, Name = "name_" + i };
            }
        }

注意每次计算表达式时都会去生成新的实例,某些情况下不知晓会非常危险。

参考:https://docs.microsoft.com/zh-cn/dotnet/csharp/linq/index

https://docs.microsoft.com/zh-cn/dotnet/csharp/expression-trees

原文地址:https://www.cnblogs.com/zhuwansu/p/10151492.html