收益回报和异常处理 [英] Yield return and exception handling

查看:64
本文介绍了收益回报和异常处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚遇到了一个使用yield return方法的情况,但没有抛出我期望的ArgumentException。我在这里用最简单的类重构了这种情况:

I just had a case with a method using yield return not throwing an ArgumentException which I expected. I have reconstructed the case with the simpliest possible classes here:

class Program
{
    static void Main(string[] args)
    {
        try
        {
            var listA = FooA(count: 0);
            Console.WriteLine("A did not throw exception!");
        }
        catch (ArgumentException)
        {
            Console.WriteLine("A threw exception!");
        }

        try
        {
            var listB = FooB(count: 0);
            Console.WriteLine("B did not throw exception!");
        }
        catch (ArgumentException)
        {
            Console.WriteLine("B threw exception!");
        }

        Console.ReadLine();
    }

    private static IEnumerable<int> FooA(int count)
    {
        if(count == 0)
            throw new ArgumentException("Count must be above 0");
        var list = new List<int>();
        for (var i = 0; i < count; i++)
        {
            list.Add(i);
        }
        return list;
    }

    private static IEnumerable<int> FooB(int count)
    {
        if (count == 0)
            throw new ArgumentException("Count must be above 0");
        for (var i = 0; i < count; i++)
        {
            yield return i;
        }
    }
}

输出:

A threw exception!
B did not throw exception!

有人可以向我解释为什么FooB在FooA不会抛出异常吗?

Can some one please explain to me why FooB does not throw an exception while FooA does?

推荐答案

这是因为 FooB 从未被评估过。

It's because FooB is never even evaluated.

调用方法时,将立即调用该方法。当您使用 yield 并返回一个可枚举值时,仅当某些东西需要使用返回的值时才调用该方法,而一次只使用一个项。这就是 yield ing的好处。

When you call a method, that method is called immediately. When you use yield and return an enumerable, that method is only called when something needs to use the value returned, and only a single item at a time; this is the benefit of yielding.

因此,如果添加使用值的东西

So, if you add something that uses the value

try
{
    var listB = FooB(count: 0);
    Console.WriteLine(listB.First()); // use the IEnumerable returned
    Console.WriteLine("B did not throw exception!");
}
catch (ArgumentException)
{
    Console.WriteLine("B threw exception!");
}

您将看到预期的结果。

You will see your expected result.

这篇关于收益回报和异常处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆