Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# foreach上的IEnumerable实现中断_C#_Linq_Foreach_Enumeration - Fatal编程技术网

C# foreach上的IEnumerable实现中断

C# foreach上的IEnumerable实现中断,c#,linq,foreach,enumeration,C#,Linq,Foreach,Enumeration,我正在使用PDFNet库从PDF中提取对象,然后是OCR。我实例化我的元素对象: public class Processor { public static int Main(string[] args) { Elements pdfPageElements = new Elements(pdfPage); ... 构造函数(在单独的类中)如下所示 internal class Elements : IEnumerator<Element&

我正在使用PDFNet库从PDF中提取对象,然后是OCR。我实例化我的
元素
对象:

public class Processor
{
    public static int Main(string[] args)
    {
       Elements pdfPageElements = new Elements(pdfPage);
       ...

构造函数(在单独的类中)如下所示

internal class Elements : IEnumerator<Element>, IEnumerable<Element>
{
    private readonly int _position;
    private readonly ElementReader _pdfElements;
    private Element _current;

    public Elements(Page currentPage)
    {
        _pdfElements = new ElementReader();
        _pdfElements.Begin(currentPage);
        _position = 0;
    }

    ...

PDFNet SDK实现MoveNext()方法,如下所示:

public bool MoveNext()
{
   if ((_current = _pdfElements.Next()) != null)
    {
        return true;
    }
    else
    {
        _pdfElements.Dispose();
         return false;
     }
 }

pdfPageImages
安装良好<代码>控制台.WriteLine(pdfPageImages.Count())为我的测试PDF返回正确数量的图像

但是当我通过
foreach循环发送
pdfPageImages
时,我得到以下异常:

pdftron.Common.PDFNetException: Unknown exception.
 at pdftron.PDF.ElementReader.Next()
 at pdftron.Elements.MoveNext()
 at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
 at DM_PDFProcessor.Processor.Main(String[] args)

可能值得注意的是,PDFNet文档中指出:

Every call to ElementReader::Next() destroys the current Element. 
Therefore, an Element becomes invalid after subsequent 
ElementReader::Next() operation.
然而,一旦元素被读入IEnumerable pdfPageImages,它就应该是无限期可编辑的(根据我有限的理解)


请注意,集合中的元素肯定不是null。你知道为什么我总是遇到例外吗?

注意

var pdfPageImages = (from e in pdfPageElements
                     where
                         (e.GetType() == Element.Type.e_inline_image ||
                          e.GetType() == Element.Type.e_image)
                     select e);
被懒惰地评估。也就是说,每次枚举
pdfPageImages
,也会枚举
pdfPageElements
。因此,如果构建
Elements
类时,实例只能枚举一次而不抛出,则可能需要缓存查询结果:

var pdfPageImages = (from e in pdfPageElements
                     where
                         (e.GetType() == Element.Type.e_inline_image ||
                          e.GetType() == Element.Type.e_image)
                     select e).ToList();

它实现
IEnumerable
IEnumerator
的事实几乎总是一个坏兆头,除非它是使用迭代器块实现的(在这种情况下,编译器会做正确的事情)。听起来像是
元素
类被设计破坏了。如果
Count()
方法在集合上迭代(如果没有
Count
属性或类似的属性,它就会这样做),那么
ElementReader::Next
方法会在访问每个元素后销毁它。因此,下次尝试迭代集合时,元素不再有效。
var pdfPageImages = (from e in pdfPageElements
                     where
                         (e.GetType() == Element.Type.e_inline_image ||
                          e.GetType() == Element.Type.e_image)
                     select e).ToList();