using(){}块内的yield return语句在执行前处置

问题描述 投票:50回答:2

我已经编写了自己的自定义数据层以持久保存到特定文件,并使用自定义DataContext模式对其进行了抽象。

这全部基于.NET 2.0框架(对目标服务器有限制),因此,即使其中一些看起来像LINQ-to-SQL,但并非如此!我刚刚实现了类似的数据模式。

请参见下面的示例,以说明我无法解释的情况。

获取Animal的所有实例-我这样做,并且效果很好

public static IEnumerable<Animal> GetAllAnimals() {
        AnimalDataContext dataContext = new AnimalDataContext();
            return dataContext.GetAllAnimals();
}

以及下面GetAllAnimals()AnimalDataContext方法的实现

public IEnumerable<Animal> GetAllAnimals() {
        foreach (var animalName in AnimalXmlReader.GetNames())
        {
            yield return GetAnimal(animalName);
        }
}

AnimalDataContext实现了IDisposable,因为我在那里有一个XmlTextReader,并且我想确保快速清除它。

现在,如果我将第一个调用包裹在这样的using语句中

public static IEnumerable<Animal> GetAllAnimals() {
        using(AnimalDataContext dataContext = new AnimalDataContext()) {
            return dataContext.GetAllAnimals();
        }
}

AnimalDataContext.GetAllAnimals()方法的第一行处放置一个断点,在AnimalDataContext.Dispose()方法的第一行中放置另一个断点,然后执行...

Dispose()方法被称为FIRST,因此AnimalXmlReader.GetNames()给出“未将对象引用设置为对象实例”例外,因为AnimalXmlReader中已将null设置为Dispose()? ??

有什么想法吗?我有一种直觉,就是与yield return相关的不允许在try-catch块内调用,而using则在编译后有效地表示了该块。]

c# .net-2.0 idisposable using yield-return
2个回答
58
投票

[当您调用GetAllAnimals时,它实际上不会执行任何代码,直到您在foreach循环中枚举返回的IEnumerable。


11
投票

之所以这样,是因为GetAllAnimals方法不会返回动物的colleciton。它返回一个能够一次返回动物的枚举器。

© www.soinside.com 2019 - 2024. All rights reserved.