C#-Linq

发布时间 2023-05-10 10:30:06作者: 懒树懒

linq可以对多种数据源和对象进行查询,如数据库、数据集、XML文档、数组等。

通过对linq的使用,可以减少代码量并优化检索操作。

LINQ关键字

from 指定数据源和范围变量

where 根据布尔表达式(由逻辑与 或 等组成)从数据源中筛选元素

select 指定查询结果中的元素所具有的类型或表现形式

group 对对查询结果按照键值进行分组

into 提供一个标示符,它可以充当对 join group 或 select 子句结果的引用

orderby 对查询出的元素进行排序

join 按照两个指定匹配条件来联接俩个数据源

let 产生一个用于查询表达式中子表达式查询结果的范围变量

1. 组成

复制代码
            // 1,获取数据源
            List<int> numbers = new List<int>() { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
        </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 2,创建查询</span>
        <span style="color: rgba(0, 0, 255, 1)">var</span> numQuery = <span style="color: rgba(0, 0, 255, 1)">from</span> num <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> numbers
                       </span><span style="color: rgba(0, 0, 255, 1)">where</span> num % <span style="color: rgba(128, 0, 128, 1)">2</span> == <span style="color: rgba(128, 0, 128, 1)">0</span>
                       <span style="color: rgba(0, 0, 255, 1)">select</span><span style="color: rgba(0, 0, 0, 1)"> num;

        </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 3,执行查询</span>
        <span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> num <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> numQuery)
        {
            Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{0,1}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, num);
        }</span></pre>
复制代码
复制代码
         static void Main(string[] args)
        {
            //获取数据源
            string[] names = { "Alen", "Zhen", "Chen","Song", "Hel", "Ken", "Aln", "Zen", "Cen", "He", "Ke", };
            //创建查询
            var queryResults = from n in names where n.StartsWith("S") select n;
            Console.WriteLine("Names beginning with S:");
            //执行查询
            foreach (var item in queryResults)
            {
                Console.WriteLine(item);
            }
            Console.Write("Program finished,press Enter/Reurn to continue:");
            Console.ReadLine();
        }
复制代码

2. 语句使用

复制代码
            //1.用var关键字声明结果变量
            //2.指定数据源:from 子句
            //3.指定条件:where 子句
            //4.指定元素:select子句
            //5.完成:使用foreach循环
            string[] names = { "Alono", "Zheng", "Yuan", "Song", "Simle", "Hsieh", "Small", "She", "Sza", "Sam", "Fa", "Iyl" };
            var queryResults = from n in names
                               where n.StartsWith("S")
                               orderby n descending//按照最后一个字母排序 ordeby n.Substring(n.Length - 1)
                               select n;//查询语法
            var queryResults1 = names.OrderBy(n => n).Where(n => n.StartsWith("S"));//方法语法 Lambda 表达式
                                                                                   // var queryResults = names.OrderByDescending(n => n).Where(n => n.StartsWith("S"));
            foreach (var item in queryResults)
                Console.WriteLine(item);
            Console.ReadKey();
复制代码

2.1  from语句   

创建一个LINQ表达式必须要以from子句开头

单个from语句

复制代码
          //获取数据
            string[] a = { "日本","德国","英国","美国","澳大利亚"};
            //创建查询,创建一个LINQ表达式必须要以from子句开头
            var myQuery = from n in a where n.IndexOf("") > 0 select n;
            //执行查询
            foreach(var item in myQuery)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
复制代码

 

 

 复合from子句

如果一个集合中的某个对象依旧是一个集合,就可以使用from子句进行筛选。

复制代码
    public class CustomerInfo1
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public List<string> TelTable { get; set; }
    }
    class Test03_MultiFrom
    {
        static void Main(string[] args)
        {
            //获取数据源
            List<CustomerInfo1> customer = new List<CustomerInfo1>
            {
                new CustomerInfo1{Name = "郭啸天",Age = 100,TelTable = new List<string>{"123321","321123"}},
                new CustomerInfo1{Name = "郭靖",Age = 80,TelTable = new List<string>{"456654","654456"}},
                new CustomerInfo1{Name = "郭芙", Age = 60,TelTable = new List<string>{"789987","987789"}}
            };
            //创建查询
            var query = from CustomerInfo1 ci in customer
                        from tel in ci.TelTable
                        where tel.IndexOf("789987") > -1
                        select ci;
 var query1=customer.SelectMany(c => c.TelTable, (c,r) => new { CustomerInfo1 = c, Tel = r }).Where(u=>u.Tel.IndexOf("789987")>-1);
//执行查询 foreach (var item in query) { Console.WriteLine("姓名:{0} 年龄:{1}", item.Name, item.Age); foreach (var tel in item.TelTable) { Console.WriteLine("电话:{0}", tel); } } Console.ReadKey();
    }
}</span></pre>
复制代码

2.2 where 语句

where子句的作用就是筛选元素,除了开始和结束位置, where子句几乎可以出现在LINQ表达式的任意位置。一个LINQ表达式中可以有where子句,也可以没有;可以有一个,可以有多个;多个where子句之间的关系相当于逻辑“与”,每个where子句可以包含1个或多个逻辑表达式,这些条件成为“谓词”,多个谓词之间用布尔运算符隔开,比如逻辑“与”用&&,逻辑“或”用||,而不是用SQL中的AND或OR。

//查询语句
var
racrers = from r in Formulal.GetChampions() where r.Wins > 15 && (r.Country == "China" || r.Country == "UK") select r;
//扩展方法
var
racres2 = Formulal.GetChampions() .Where(r => r.Wins > 15 && (r.Country == "China" || r.Country == "UK")) .Select(r => r);

这两种执行的结果都是一样的。但是并不是所有的LINQ查询都可以使用LINQ查询表达式完成,也不是所有的LINQ扩展方法都能够映射到LINQ查询表达式语句上。LINQ扩展方法使用的范围要比查询表达式更广泛,尤其是一些高级查询,只能或更多的是使用扩展方法完成。同时,这两种形式也可以组合使用。

//使用索引筛选,只能使用扩展方法,不能使用Linq查询语句
var racers3 = Formulal.GetChampions()
    .Where((r, index) => r.LastName.StartsWith("A") && index % 2 != 0);

2.3 排序子句 

 OrderBy/OrderByDescending/ThenBy/ThenByDescending

OrderBy():按升序对序列的元素进行排序。

ThenBy():按升序对序列中的元素进行后续排序。

OrderByDescending():按降序对序列的元素进行排序。

ThenByDescending():按降序对序列中的元素进行后续排序。

//查询语句
var racers3 = (from r in Formulal.GetChampions()
               orderby r.Country, r.LastName, r.FirstName ascending
               select r).Take(10);
复制代码
//扩展方法
var racers4 = Formulal.GetChampions()
    .OrderBy(r => r.Country)
    .ThenBy(r => r.LastName)
    .ThenByDescending(r => r.FirstName)
    .Take(10);
复制代码

2.4 分组

  GroupBy

如果要根据一个关键字值 对查询结果分组,可以使用group子句。对应的扩展方法为GroupBy()

复制代码
//查询语句
var countries = from r in Formulal.GetChampions()
                group r by r.Country into g //将分组信息放入标识符g中
                orderby g.Count() descending, g.Key
                where g.Count() >= 2
                select new
                {
                    Country = g.Key,
                    Count = g.Count()
                }
复制代码
复制代码
//扩展方法
var countries2 = Formulal.GetChampions()
    .GroupBy(r => r.Country)
    .OrderByDescending(g => g.Count())
    .ThenBy(g => g.Key)
    .Where(g => g.Count() >= 2)
    .Select(g => new { Country = g.Key, Count = g.Count() });
复制代码

2.5  Let子句  及   匿名类属性

上述的分组查询语句,中间多次调用了Count方法,使用let子句可以改变这种方式。let允许在LINQ查询中定义变量。

复制代码
var countries = from r in Formulal.GetChampions()
                group r by r.Country into g
                let count = g.Count()
                orderby count descending, g.Key
                where count >= 2
                select new
                {
                    Country = g.Key,
                    Count = count
                };
复制代码

使用方法语法时,为了避免Count方法被调用多次,可以使用Select方法创建一个匿名类型,将Count方法的结果作为匿名类的属性进行传递

复制代码
var countries2 = Formulal.GetChampions()
    .GroupBy(r => r.Country)
    .Select(g => new { Group = g, Count = g.Count() })
    .OrderByDescending(g => g.Count)
    .ThenBy(g => g.Group.Key)
    .Where(g => g.Count >= 2)
    .Select(g => new
    {
        Country = g.Group.Key,
        Count = g.Count
    });
复制代码

注意:应考虑根据let子句或Select方法创建的临时对象的数量 。查询大列表时,创建的大量对象需要以后进行垃圾收集 ,这可能对性能产生巨大影响。

2.6  join子句

如果一个数据源中元素的某个属性可以跟另一个数据源中元素的属性进行相等比较,那么这两个数据源可以用join子句进行关联。jion子句用equals关键字进行比较,而不是常见的==。
复制代码
var racersAndTeams = (from r in racers
                       join t in teams on r.Year equals t.Year
                       orderby t.Year
                       select new
                          {
                                      r.Year,
                                      Champion = r.Name,
                                      Constructor = t.Name
                          }).Take(10);
复制代码

左外连接

复制代码
var racersAndTeams = (from r in racers
                      join t in teams on r.Year equals t.Year into rt
                      from t in rt.DefaultIfEmpty()
                      orderby r.Year
                      select new
                      {
                          r.Year,
                          Champion = r.Name,
                          Constructor = t == null ? "no constructor" : t.Name
                      }).Take(10);
复制代码

 

2.7 集合操作

Intersect():通过使用的默认相等比较器对值进行比较,生成两个序列的交集。

Distinct():返回序列中通过使用指定的非重复元素。

Union():通过使用默认的相等比较器生成的两个序列的并集。

Except():通过使用默认的相等比较器对值进行比较,生成两个序列的差集。

复制代码
           List<Order> orders = new List<Order>{
            new Order {ID="A",Amount=100},
            new Order {ID ="B",Amount =200},
            new Order {ID ="H",Amount =300}};
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> customersIDs = <span style="color: rgba(0, 0, 255, 1)">from</span> c <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> customers
                           </span><span style="color: rgba(0, 0, 255, 1)">select</span><span style="color: rgba(0, 0, 0, 1)"> c.ID;
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> ordersIDs = <span style="color: rgba(0, 0, 255, 1)">from</span> o <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> orders
                        </span><span style="color: rgba(0, 0, 255, 1)">select</span><span style="color: rgba(0, 0, 0, 1)"> o.ID;
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> customersWithOrders = customersIDs.Intersect(ordersIDs);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">Intersect()</span>
        <span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> item <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> customersWithOrders )
            Console.WriteLine(item );
        Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">-------------------------</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> ordersNoCustomers = ordersIDs.Except(customersIDs);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">Except()</span>
        <span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> item <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> ordersNoCustomers )
            Console.WriteLine(item );
        Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">-------------------------</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> allCustomersOrders = ordersIDs.Union(customersIDs);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">Union()</span>
        <span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> item <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> allCustomersOrders)
            Console.WriteLine(item);
        </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">Console.ReadKey();</span></pre>
复制代码

2.8 分区 

 Take和TakeWhile,Skip和SkipWhile

Take():从序列的开头返回指定的数量的连续元素。
TakeWhile():只要指定的条件为true,就返回序列中的元素,然后跳过其余元素。
Skip():跳过指定的数量的序列中的元素,然后返回剩余元素。
SkipWhile():只要指定的条件为真,就会跳过序列中的元素,然后返回剩余的元素。

复制代码
int pageSize = 5;
int numberPages = (int)Math.Ceiling(Formulal.GetChampions().Count() / (double)pageSize);

for (int page = 0; page < numberPages; page++)
{
Console.WriteLine(
"Page "+page);

</span><span style="color: rgba(0, 0, 255, 1)">var</span> racers = (<span style="color: rgba(0, 0, 255, 1)">from</span> r <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> Formulal.GetChampions()
              </span><span style="color: rgba(0, 0, 255, 1)">orderby</span><span style="color: rgba(0, 0, 0, 1)"> r.LastName, r.FirstName
              </span><span style="color: rgba(0, 0, 255, 1)">select</span> r.FirstName + <span style="color: rgba(128, 0, 0, 1)">"</span> <span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> r.LastName)
            .Skip(page </span>*<span style="color: rgba(0, 0, 0, 1)"> pageSize).Take(pageSize);

</span><span style="color: rgba(0, 0, 255, 1)">foreach</span>(<span style="color: rgba(0, 0, 255, 1)">var</span> name <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> racers)
{
    Console.WriteLine(name);
}
Console.WriteLine(  );

}

复制代码

2.9 聚合操作符

聚合操作符(如Count、Sum、Min、Max、Average和Aggregate操作符)不返回一个序列,而返回一个值。
Count():返回序列中的元素数。
Sum():计算一系列数值的总和。
Min():返回值序列中的最小值。
Max():返回值序列中的最大值。
Average():计算一系列数值的平均值。
Aggregate(): 对一个序列应用累加器函数。

复制代码
Console.WriteLine("Count():");
var query = from r in Formulal.GetChampions()
            let numberYears = r.Years.Count()
            where numberYears >= 3
            orderby numberYears descending, r.LastName
            select new
            {
                Name = r.FirstName + " " + r.LastName,
                TimesChampion = numberYears
            };

foreach(var r in query)
{
Console.WriteLine(r.Name
+" "+r.TimesChampion);
}

Console.WriteLine();
Console.WriteLine("Sum():");

var countries = (from c in from r in Formulal.GetChampions()
group r by r.Country into c
select new
{
Country
= c.Key,
Wins
= (from r1 in c select r1.Wins).Sum()
}
orderby c.Wins descending, c.Country
select c).Take(5);
foreach(var country in countries)
{
Console.WriteLine(country.Country
+" "+country.Wins);
}

复制代码

 ==============================================相关知识点扩展==================================================

相关知识点扩展

1   var 、  dynamic  及匿名类型

复制代码
 var model = new //3.0
                {
                    Id = 2,
                    Name = "undefined",
                    Age = 25,
                    ClassId = 2,
                 }  

Console.WriteLine(model.Id);     //编译错误
Console.WriteLine(model, Name);  //编译错误 

 
 dynamic model = new //4.0    dynamic避开编译器检查
                {
                    Id = 2,
                    Name = "undefined",
                    Age = 25,
                    ClassId = 2,
                 }  
Console.WriteLine(model.Id);     //编译不会报错
Console.WriteLine(model, Name);  //编译不会报错
复制代码

2.   扩展方法

数据准备

复制代码
    /// <summary>
    /// 学生实体
    /// </summary>
    public class Student
    {
        public int Id { get; set; }
        public int ClassId { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Study()
    {
        Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{0} {1}跟着Eleven老师学习.net高级开发</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(0, 0, 255, 1)">this</span>.Id, <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.Name);
    }

    </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> StudyHard()
    {
        Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{0} {1}跟着Eleven老师努力学习.net高级开发</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(0, 0, 255, 1)">this</span>.Id, <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.Name);
    }

    </span><span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)">/学习实战班</span>
    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">public void StudyPractise()
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">{
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">    Console.WriteLine("{0} {1}跟着Mark老师学习.net实战开发", this.Id, this.Name);
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">}</span>
}</pre>
复制代码
复制代码
    /// <summary>
    /// 扩展方法:静态类里面的静态方法,第一个参数类型前面加上this
    /// </summary>
    public static class ExtendMethod
    {
        public static void StudyPractise(this Student student)
        {
            Console.WriteLine("{0} {1}跟着Mark老师学习.net实战开发", student.Id, student.Name);
        }
   }
复制代码

方法调用

复制代码

//扩展方法调用,很像实例方法,就像扩展了Student的逻辑
//1 第三方的类,不适合修改源码,可以通过扩展方法增加逻辑
//优先调用实例方法,最怕扩展方法增加了,别人类又修改了
//2 适合组件式开发的扩展(.NetCore),定义接口或者类,是按照最小需求,但是在开发的时候又经常需要一些方法,就通过扩展方法 context.Response.WriteAsync 中间件的注册
//3 扩展一些常见操作
//会污染基础类型,一般少为object 没有约束的泛型去扩展


student.Study(); ExtendMethod.StudyPractise(student); student.StudyPractise();
复制代码

3.  yield 迭代器

复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MyLinq
{
/// <summary>
/// http://www.cnblogs.com/YamatAmain/p/5016464.html
///
/// 含有yield的函数说明它是一个生成器,而不是普通的函数。当程序运行到yield这一行时,该函数会返回值,并保存当前域的所有变量状态;
/// 等到该函数下一次被调用时,会从上一次中断的地方开始执行,一直遇到下一个yield, 程序返回值, 并在此保存当前状态; 如此反复,直到函数正常执行完成。
///
/// 迭代器模式是设计模式中行为模式(behavioral pattern)的一个例子,他是一种简化对象间通讯的模式,也是一种非常容易理解和使用的模式。
/// 简单来说,迭代器模式使得你能够获取到序列中的所有元素 而不用关心是其类型是array,list,linked list或者是其他什么序列结构。
/// 这一点使得能够非常高效的构建数据处理通道(data pipeline)--即数据能够进入处理通道,进行一系列的变换,或者过滤,然后得到结果。事实上,这正是LINQ的核心模式。
/// 在.NET中,迭代器模式被IEnumerator和IEnumerable及其对应的泛型接口所封装。如果一个类实现了IEnumerable接 口,那么就能够被迭代;
/// 调用GetEnumerator方法将返回IEnumerator接口的实现,它就是迭代器本身。迭代器类似数据库中的游标,他是 数据序列中的一个位置记录。
/// 迭代器只能向前移动,同一数据序列中可以有多个迭代器同时对数据进行操作。
/// </summary>
public class YieldShow
{
/// <summary>
///
/// </summary>
public void Show()
{
IEnumerable
<int> iterable = this.CreateEnumerable();//1 不会直接执行
//IEnumerator iterator = iterable.GetEnumerator();
IEnumerator<int> iterator = iterable.GetEnumerator();
Console.WriteLine(
"开始迭代");
while (true)
{
Console.WriteLine(
"调用MoveNext方法……");
Boolean result
= iterator.MoveNext();//2 正式开启CreateEnumerable
Console.WriteLine("MoveNext方法返回的{0}", result);
if (!result)
{
break;
}
Console.WriteLine(
"获取当前值……");
Console.WriteLine(
"获取到的当前值为{0}", iterator.Current);
}
Console.ReadKey();
}

    </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
    <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 普通获取数据
    </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
    <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">public</span> IEnumerable&lt;<span style="color: rgba(0, 0, 255, 1)">int</span>&gt;<span style="color: rgba(0, 0, 0, 1)"> CommonMethod()
    {
        List</span>&lt;<span style="color: rgba(0, 0, 255, 1)">int</span>&gt; results = <span style="color: rgba(0, 0, 255, 1)">new</span> List&lt;<span style="color: rgba(0, 0, 255, 1)">int</span>&gt;<span style="color: rgba(0, 0, 0, 1)">();
        </span><span style="color: rgba(0, 0, 255, 1)">int</span> counter = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
        </span><span style="color: rgba(0, 0, 255, 1)">int</span> result = <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;

        </span><span style="color: rgba(0, 0, 255, 1)">while</span> (counter++ &lt; <span style="color: rgba(128, 0, 128, 1)">10</span><span style="color: rgba(0, 0, 0, 1)">)
        {
            Thread.Sleep(</span><span style="color: rgba(128, 0, 128, 1)">1000</span><span style="color: rgba(0, 0, 0, 1)">);
            Console.WriteLine($</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">获取{counter}次数据</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
            result </span>= result * <span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">;
            results.Add(result);
        }
        </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> results;
    }
    </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
    <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> yield获取数据
    </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
    <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">public</span> IEnumerable&lt;<span style="color: rgba(0, 0, 255, 1)">int</span>&gt;<span style="color: rgba(0, 0, 0, 1)"> YieldMethod()
    {
        </span><span style="color: rgba(0, 0, 255, 1)">int</span> counter = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
        </span><span style="color: rgba(0, 0, 255, 1)">int</span> result = <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
        </span><span style="color: rgba(0, 0, 255, 1)">while</span> (counter++ &lt; <span style="color: rgba(128, 0, 128, 1)">10</span><span style="color: rgba(0, 0, 0, 1)">)
        {
            Thread.Sleep(</span><span style="color: rgba(128, 0, 128, 1)">1000</span><span style="color: rgba(0, 0, 0, 1)">);
            Console.WriteLine($</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">获取{counter}次数据</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
            result </span>= result * <span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">;
            </span><span style="color: rgba(0, 0, 255, 1)">yield</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> result;
        }
    }

    </span><span style="color: rgba(0, 0, 255, 1)">public</span> IEnumerable&lt;<span style="color: rgba(0, 0, 255, 1)">int</span>&gt;<span style="color: rgba(0, 0, 0, 1)"> CreateEnumerable()
    {
        </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">
        {
            Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{0} CreateEnumerable()方法开始</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, DateTime.Now);
            </span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i &lt; <span style="color: rgba(128, 0, 128, 1)">5</span>; i++<span style="color: rgba(0, 0, 0, 1)">)
            {
                Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{0}开始 yield {1}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, DateTime.Now, i);
                </span><span style="color: rgba(0, 0, 255, 1)">yield</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> i;
                Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{0}yield 结束</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, DateTime.Now);
                </span><span style="color: rgba(0, 0, 255, 1)">if</span> (i == <span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">)
                {
                    </span><span style="color: rgba(0, 0, 255, 1)">yield</span> <span style="color: rgba(0, 0, 255, 1)">break</span>;<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">直接终结迭代  4会出现的,,</span>

}
}
Console.WriteLine(
"{0} Yielding最后一个值", DateTime.Now);
yield return -1;
Console.WriteLine(
"{0} CreateEnumerable()方法结束", DateTime.Now);
}
finally
{
Console.WriteLine(
"停止迭代!");
}
}
}
}

复制代码