C#中的foreach和yield

1. foreach

C#编译器会把foreach语句转换为IEnumerable接口的方法和属性。

foreach (Person p in persons)
 {
     Console.WriteLine(p);
 }

foreach语句会解析为下面的代码段。

调用GetEnumerator()方法,获得数组的一个枚举

在while循环中,只要MoveNext()返回true,就一直循环下去

用Current属性访问数组中的元素

IEnumerator enumerator = persons. GetEnumerator();
 while (enumerator.MoveNext())
 {
    Person p = (Person) enumerator.Current;
    Console.WriteLine(p);
}

2. yield语句

yield语句的两种形式:

yield return <expression>;
yield break;

使用一个yield return语句返回集合的一个元素

包含yield语句的方法或属性是迭代器。迭代器必须满足以下要求

a. 返回类型必须是IEnumerableIEnumerable<T>IEnumeratorIEnumerator<T>

b. 它不能有任何ref或out参数

yield return语句不能位于try-catch快。yield return语句可以位于try-finally的try块

try
              {
                  // ERROR: Cannot yield a value in the boday of a try block with a catch clause
                 yield return "test";
              }
             catch
             { }

              try
             {
                 //
                 yield return "test again";
             }
             finally
             { }

             try
             { }
             finally
             {
                 // ERROR: Cannot yield in the body of a finally clause
                yield return "";
             }

yield break语句可以位于try块或catch块,但是不能位于finally块

下面的例子是用yield return语句实现一个简单集合的代码,以及用foreach语句迭代集合

using System;
using System.Collections.Generic;

namespace ConsoleApplication6
{
    class Program
    {
        static void Main(string[] args)
        {
            HelloCollection helloCollection = new HelloCollection();
            foreach (string s in helloCollection)
            {
                Console.WriteLine(s);
                Console.ReadLine();
            }
        }
    }

    public class HelloCollection
    {

        public IEnumerator<String> GetEnumerator()
        {
            // yield return语句返回集合的一个元素,并移动到下一个元素上;yield break可以停止迭代
            yield return "Hello";
            yield return "World";
        }
    }
}

使用yield return语句实现以不同方式迭代集合的类:

using System;
using System.Collections.Generic;

namespace ConsoleApplication8
{
    class Program
    {
        static void Main(string[] args)
        {
            MusicTitles titles = new MusicTitles();
            foreach (string title in titles)
            {
                Console.WriteLine(title);
            }
            Console.WriteLine();

            foreach (string title in titles.Reverse())
            {
                Console.WriteLine(title);
            }
            Console.WriteLine();

            foreach (string title in titles.Subset(2, 2))
            {
                Console.WriteLine(title);
                Console.ReadLine();
            }
        }
    }

    public class MusicTitles
    {
        string[] names = { "a", "b", "c", "d" };
        public IEnumerator<string> GetEnumerator()
        {
            for (int i = 0; i < 4; i++)
            {
                yield return names[i];
            }
        }

        public IEnumerable<string> Reverse()
        {
            for (int i = 3; i >= 0; i--)
            {
                yield return names[i];
            }
        }

        public IEnumerable<string> Subset(int index, int length)
        {
            for (int i = index; i < index + length; i++)
            {
                yield return names[i];
            }
        }
    }
}

以上动图由“图斗罗”提供

时间: 2024-10-09 10:54:55

C#中的foreach和yield的相关文章

C#中的IEnumerator、foreach、yield

[C#中的IEnumerator.foreach.yield] 1.IEnumerator,是一个接口,它的方法如下: 2.foreach语句,在编译后会变成IEnumerator的调用: 3.yield用于return一个IEnumerator. 参考:http://wenku.baidu.com/link?url=3wR-rCcSOQtNOGcz3uaWG_EAyGfRqcNER1jbOEd7H57qw4ZRWnWatpAO6_WkAzUSRPorCXdy7vnT4I23tvPFpcX8xO

C#中,什么时候用yield return

yield关键字用于遍历循环中,yield return用于返回IEnumerable<T>,yield break用于终止循环遍历. 有这样的一个int类型的集合: static List<int> GetInitialData() { return new List<int>(){1,2,3,4}; } 需要打印出所有值大于2的元素. 不使用yield return的实现 static IEnumerable<int> FilterWithoutYiel

C#-foreach与yield

(转自:http://www.jb51.net/article/34627.htm) 1. foreach语句 C#编译器会把foreach语句转换为IEnumerable接口的方法和属性. ? 1 2 3 4 foreach (Person p in persons) {     Console.WriteLine(p); } foreach语句会解析为下面的代码段. ?调用GetEnumerator()方法,获得数组的一个枚举?在while循环中,只要MoveNext()返回true,就一直

lock中使用迭代返回yield return是否会释放锁?

项目中遇到一个问题如题,于是做了个小实验,发现在lock中yield return并不会释放该lock,直到整个迭代器完全执行完或者yield break后才会释放lock. 1 class Program 2 { 3 static object mylock = new object(); 4 static long index = 0xff; 5 6 static void Main(string[] args) 7 { 8 System.Threading.Thread t1 = new

C#编程(三十五)----------foreach和yield

枚举 在foreach语句中使用枚举,可以迭代集合中的元素,且无需知道集合中的元素个数. 数组或集合实现带GetEumerator()方法的IEumerable接口.GetEumerator()方法返回一个实现IEunmerable接口的枚举. GetEnumerator()方法用IEnumerable接口定义.foreach语句并不真的需要在集合类中实现这个借口.有一个名为GetEnumerator()的方法,他返回实现了IEnumerator接口的对象就足够了. IEnumerator接口

C#高级编程三十五天----foreach和yield

枚举 在foreach语句中使用枚举,可以迭代集合中的元素,且无需知道集合中的元素个数. 数组或集合实现带GetEumerator()方法的IEumerable接口.GetEumerator()方法返回一个实现IEunmerable接口的枚举. GetEnumerator()方法用IEnumerable接口定义.foreach语句并不真的需要在集合类中实现这个借口.有一个名为GetEnumerator()的方法,他返回实现了IEnumerator接口的对象就足够了. IEnumerator接口

php中的foreach使用

foreach语句是php用来遍历数组的一种方法,主要有两种格式: 第一种:foreach (array_name as $value) 例1: <?php$arr=array(1,2,3);foreach ($arr as $key =>$value){ echo "Value: " . $value . "<br />";}?> 运行结果: 第二种:foreach  (array_name as $key => $value)

“mybatis 中使用foreach 传

为了帮助网友解决“mybatis 中使用foreach 传”相关的问题,中国学网通过互联网对“mybatis 中使用foreach 传”相关的解决方案进行了整理,用户详细问题包括:mybatismapsql <update id="updateallByEntity" parameterType="java.util.List"> update T_WEEKDAY <foreach item="item" index="

二、C++迭代器的两种实现方式 (Range for和C#、Java中的foreach)

一.迭代器概述 这个标题其实有点"标题党"的含义,因为C++在标准库中的实现迭代器的方式只有一种,也就是为类定义begin()和end()函数,C++11增加了range for语句,可以用来遍历迭代器中的元素.实现迭代器的第二种方式,就是用C++模拟C#和Java中的迭代器模式,并且我们可以定义出自己的foreach语句.除此之外,迭代器可能还有很多种实现的方法,各个库也会多自己的迭代器的实现有所定义,在这里只要明白迭代器的本质意义即可. 迭代器,也称作游标,是一种设计模式,我们可以