C# foreach上的IEnumerable实现中断
我正在使用PDFNet库从PDF中提取对象,然后是OCR。我实例化我的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&
元素
对象:
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();