在.Net中yield是一个关键字,在一些项目中也常用到。下面用一个最简单的例子来说明它的使用场景。以下两段代码的执行效果是一样的:

  public IEnumerable<int> GetCollection1()
        {
            IList<int> list = new List<int>();
            for(int i = 0; i < 10; i++)
            {
                list.Add(i);
            }
            return list;
        }
 public IEnumerable<int> GetCollection2()
        {
            for (int i = 0; i < 10; i++)
            {
                yield return i;
            }
        }

这就是yield独到之处,它不需要容器就可以直接返回数据集,那这样的话性能会提高么?答案是肯定的,可以做以下测试,需要注意的是使用yield时没有使用数据集只是返回引用地址,所以只在遍历的过程中才能真正意义上看到它的效率。于是我们的测试代码如下:

[Test]
        public void YelidTest()
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            var r1 = GetCollection1();
            foreach(var i in r1)
            {

            }
            sw.Stop();
            Console.WriteLine($"Collection1:{sw.ElapsedMilliseconds}");
            sw.Restart();
            var r2 = GetCollection2();
            foreach (var i in r2)
            {

            }
            sw.Stop();
            Console.WriteLine($"Collection2:{sw.ElapsedMilliseconds}");
        }

两个方法也加大了数据范围如下:

public IEnumerable<int> GetCollection1()
        {
            IList<int> list = new List<int>();
            for (int i = 0; i < 1000000; i++)
            {
                list.Add(i);
            }
            return list;
        }

        public IEnumerable<int> GetCollection2()
        {
            for (int i = 0; i < 1000000; i++)
            {
                yield return i;
            }
        }

最终输出:Collection1:1998 Collection2:1411
我使用的是在NetCore中的单元测试,在framework下同理。这里只是使用int类型测试如果使用复杂的引用类型更能体现出他们的差距。
另外还有yield break;的用法,简单示例如下:

yield return 1;
yield return 2;
yield return 3;
yield break;
yield return 4;

这种情况下4不会被包含在结果集中。

最后是yield的使用限制

不能将 yield return 语句置于 try-catch 块中。 可将 yield return 语句置于 try-finally 语句的 try 块中。
可将 yield break 语句置于 try 块或 catch 块中,但不能将其置于 finally 块中。
如果 foreach 主体(在迭代器方法之外)引发异常,则将执行迭代器方法中的 finally 块。


详细信息见官网:yield(C# 参考)

原创内容禁止转载!

推荐文章:

C# 通过Expression高效的把dynamic转成实体类

C# new IEnumerable 怎么初始化?

C# 中yield 的用法以及性能提升

C# 字符串转成枚举正确的方法

c# 无损高质量压缩图片

C# List Sort 自定义排序方法实现