语言集成查询 (LINQ) 是一系列直接将查询功能集成到 C# 语言的技术统称。
查询表达式(生成表达式)
1、IEnumerable<T> 查询编译为委托。如 source.Where(m=>m.Id>1) 返回一个表达式,这个表达式可以转为委托。
2、 IQueryable 和 IQueryable<T> 查询编译为表达式树。
存储查询结果(计算表达式)
- foreach、序列化、求值 或其他访问数据项的行为
两个测试帮助理解 什么是生成表达式什么是计算表达式
public static class ListTest
{
public static List<T1> Source { get; set; } = new List<T1>
{
new T1{ Id=, Name="" },
new T1{ Id=, Name="" },
new T1{ Id=, Name="" },
new T1{ Id=, Name="" },
new T1{ Id=, Name="" },
new T1{ Id=, Name="" },
new T1{ Id=, Name="" },
new T1{ Id=, Name="" },
new T1{ Id=, Name="" },
};
public static void Test()
{
//注意循环性能 foreach (T1 item in Source)
{
if (item.Id <= )
{
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 > ;
}))
{
//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 == ), s2.First(m => m.Id == )))
{
System.Console.WriteLine("同实例");
}
else
{
System.Console.WriteLine("不同实例");
}
System.Console.ReadLine();
} private static IEnumerable<T1> Init()
{
for (int i = ; i < ; 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