zoukankan      html  css  js  c++  java
  • LINQ基础知识

    议程

    1.LINQ和LINQ表达式

    2.Lambda表达式

    两个接口

    IEnumerable <T> 泛型接口

    公开枚举数,该枚举数支持在指定类型的集合上进行简单迭代。

    public class MyCollections<T> : IEnumerable<T>

    {

    T[] values = new T[100];

    public IEnumerator<T> GetEnumerator()

    {

    for (int i = 0; i < 100; i++)

    {

    yield return values[i];

    }

    }

    IEnumerator IEnumerable.GetEnumerator()

    {

    return GetEnumerator();

    }

    }

    class Class2

    {

    static void Main()

    {

    MyCollections<int> Mycol = new MyCollections<int>();

    foreach (int i in Mycol)

    {

    Console.WriteLine(i);

    }

    }

    }

    Iqueryable<T>

    提供对数据类型已知的特定数据源的查询进行计算的功能。

    此接口继承 IEnumerable<T>接口,因此,如果它表示一个查询,则可以枚举该查询的结果。枚举强制执行与 Iqueryable<T>对象关联的表达式目录树。

    LINQ基本概念

    LINQ:语言集成查询(Language Integrated Query),是一系列标准查询操作符的集合,这些操作符几乎对每一种数据源的导航,过滤和执行都是提供了底层的基本查询架构。

    LINQ可查的数据源包括关系数据,XML,DataSet或内存中的数据。

    LINQ出现的背景:大多数开发人员对OO的熟悉,最好提把对数据的操作转化成对对象的操作。

    LINQ恰好将标准查询功能直接整合到了供开发人员选择的基于.NET的编程语言中。

    LINQ支术的重点是查询表达式,因为它描述了对数据源的具体操作。

    LINQ查询表达式基本概念

    1.查询表达式可用于查询和转换来自任意支持 LINQ 的数据源中的数据。例如,单个查询可以从 SQL 数据库检索数据,并生成 XML 流作为输出。

    2.查询表达式容易掌握,因为它们使用许多常见的 C# 语言构造。

    3.查询表达式中的变量都是强类型的,但许多情况下您不需要显式提供类型,因为编译器可以推断类型。

    4.在您循环访问 foreach 语句中的查询变量之前,不会执行查询。

    5.在编译时,根据 C# 规范中设置的规则将查询表达式转换为“标准查询运算符”方法调用。任何可以使用查询语法表示的查询也可以使用方法语法表示。但是,在大多数情况下,查询语法更易读和简洁。

    6.作为编写 LINQ 查询的一项规则,建议尽量使用查询语法,只在必需的情况下才使用方法语法。这两种不同形式在语义或性能上没有区别。查询表达式通常比用方法语法编写的等效表达式更易读。

    7.一些查询操作,如 Count 或 Max,没有等效的查询表达式子句,因此必须表示为方法调用。方法语法可以通过多种方式与查询语法组合。

    8.查询表达式可以编译为表达式目录树或委托,具体取决于查询所应用到的类型。IEnumerable<(Of <(T>)>) 查询编译为委托。IQueryable 和 IQueryable<(Of <(T>)>) 查询编译为表达式目录树。

    LINQ查询表达式

    查询操作包含三部分:

    1. 获取数据源
    2. 创建查询
    3. 执行查询

    Demo:

    //获取数据源

    string[] Devices= {"电视" ,"电冰箱","洗衣机","电话","微波炉"};

    //创建查询

    var SelectDevices = from device in Devices

    where device.StartsWith("电")

    select device;

    //执行查询

    foreach (string dev in SelectDevices)

    {

    Console.WriteLine("带电的设备:{0}",dev);

    }

    匿名方法

    在 2.0 之前的 C# 版本中,声明委托的唯一方法是使用命名方法。C# 2.0 引入了匿名方法,而在 C# 3.0 及更高版本中,Lambda 表达式取代了匿名方法,作为编写内联代码的首选方式。不过,本主题中有关匿名方法的信息同样也适用于 Lambda 表达式。有一种情况下,匿名方法提供了 Lambda 表达式中所没有的功能。匿名方法使您能够省略参数列表,这意味着可以将匿名方法转换为带有各种签名的委托。这对于 Lambda 表达式来说是不可能的。

    button1.Click += delegate(System.Object o, System.EventArgs e)//匿名方法参数

    {//匿名方法方法体

    MessageBox.Show("Click!");

    }; 

    Lambda表达式

    • “Lambda 表达式”是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型。
    • 所有 Lambda 表达式都使用 Lambda 运算符 =>,该运算符读为“goes to”。该 Lambda 运算符的左边是输入参数(如果有),右边包含表达式或语句块。Lambda 表达式 x => x * x 读作“x goes to x times x”。可以将此表达式分配给委托类型

    static void Main()

    {

    del myDelegate = x => x * x;

    int j = myDelegate(5); //j = 25

    Console.WriteLine(j);

    }

    delegate int del(int i);

    • 只有在 Lambda 有一个输入参数时,括号才是可选的;否则括号是必需的。两个或更多输入参数由括在括号中的逗号分隔:

    (x, y) => x == y

    • 有时,编译器难于或无法推断输入类型。如果出现这种情况,您可以按以下示例 中所示方式显式指定类型:

    (int x, string s) => s.Length > x

    uLambda 语句与 Lambda 表达式类似,只是语句括在大括号中:

    delegate void TestDelegate(string s);

    TestDelegate myDel = n => { string s = n + " " + "World"; Console.WriteLine(s); };

    myDel("Hello");

    • 在编写 Lambda 时,通常不必为输入参数指定类型,因为编译器可以基于 Lambda 主体、基础委托类型以及 C# 3.0 语言规范中描述的其他因素推断类型。对于大多数标准查询运算符,第一个输入是源序列中的元素的类型。因此,如果要查询 IEnumerable<Customer>,则输入变量将被推断为 Customer类型,这意味着您可以访问其方法和属性:

    customers.Where(c => c.City == "London");

    • 有时,编译器难于或无法推断输入类型。如果出现这种情况,您可以按以下示例 中所示方式显式指定类型:

    (int x, string s) => s.Length > x

    uLambda 语句与 Lambda 表达式类似,只是语句括在大括号中:

    delegate void TestDelegate(string s);

    TestDelegate myDel = n => { string s = n + " " + "World"; Console.WriteLine(s); };

    myDel("Hello");

    • 在编写 Lambda 时,通常不必为输入参数指定类型,因为编译器可以基于 Lambda 主体、基础委托类型以及 C# 3.0 语言规范中描述的其他因素推断类型。对于大多数标准查询运算符,第一个输入是源序列中的元素的类型。因此,如果要查询 IEnumerable<Customer>,则输入变量将被推断为 Customer类型,这意味着您可以访问其方法和属性:

    customers.Where(c => c.City == "London");

    Lambda 的一般规则如下:

    • Lambda 包含的参数数量必须与委托类型包含的参数数量相同。
    • Lambda 中的每个输入参数必须都能够隐式转换为其对应的委托参数。
    • Lambda 的返回值(如果有)必须能够隐式转换为委托的返回类型。

    Lambda 可以引用“外部变量”,这些变量位于在其中定义 Lambda 的封闭方法或类型的范围内。将会存储通过这种方法捕获的变量以供在 Lambda 表达式中使用,即使变量将以其他方式超出范围或被作为垃圾回收。必须明确地分配外部变量,然后才能在 Lambda 表达式中使用该变量。

    • 捕获的变量将不会被作为垃圾回收,直至引用变量的委托超出范围为止。
    • 在外部方法中看不到 Lambda 表达式内引入的变量。
    • Lambda 表达式无法从封闭方法中直接捕获 ref 或 out 参数。
    • Lambda 表达式中的返回语句不会导致封闭方法返回。
    • Lambda 表达式不能包含其目标位于所包含匿名函数主体外部或内部的 goto 语句、break 语句或 continue 语句。

    查询语法和方法语法

    string[] Devices= {"电视" ,"电冰箱","洗衣机","电话","微波炉"};

    查询语法

    var SelectDevices = from device in Devices

    where device.StartsWith("电")

    select device;

    方法语法

    var SelectDevices =Devices .Where ( device => device.StartsWith("电"))

    foreach (string dev in SelectDevices)

    {

    Console.WriteLine("带电的设备:{0}",dev);

    }

    image

  • 相关阅读:
    嵌入式培训学习历程第二十四天
    嵌入式培训学习历程第二十三天
    嵌入式培训学习历程第二十二天
    嵌入式培训学习历程第二十一天
    嵌入式培训学习历程第二十天
    嵌入式培训学习历程第十九天
    嵌入式培训学习历程第十八天
    嵌入式培训学习历程第十七天
    嵌入式培训学习历程第十六天
    系统编程之进程的创建.僵尸与孤儿进程
  • 原文地址:https://www.cnblogs.com/axzxs2001/p/1552650.html
Copyright © 2011-2022 走看看