Reivt:过滤器FilteredElementIterator,采集器FilteredElementCollector

事先说明,由于本人是刚接触Revit,所有知识点,都是我自己一边研究一边写的。所以,可能是有错误的,若有错误,还望指正和海涵。

题目的这2个东西,如果你懂设计模式的迭代模式的话,是极其容易理解的。

他们分别继承实现了微软框架官方接口:IEnumerator、IEnumerable。

简单说一下迭代模式,它需要声明两种接口,一种接口是表明可以被枚举:IEnumerable,另一种接口是要表明这是一个枚举器。可以被枚举 和 枚举器,是不一样的概念。只要搞清楚这2个概念,那么迭代模式是很简单的。任何一个类,不能同时实现这2个接口,即:任何一个类不能既是可以被枚举,然后又还是枚举器。他们一定是分开的。至于为什么一定是分开的,那么就是你的面向对象的基础问题,这个我就不培训你了。

好了,那么按迭代模式来看Revit这个过滤器和采集器。过滤器FilteredElementIterator就是表明可以被枚举,采集器FilteredElementCollector就是枚举器(或者也叫迭代器)。

他们的源码如下:

从上面的源码中可以看到,这个Revit过滤器是一个很有意思的东西, 

public FilteredElementCollector(Document document);他的构造函数全部都是Document对象。之前文章有说过Document对象可能是最具体的文档对象了,他里面可以访问当前文档的所有选中的元素。

public FilteredElementCollector(Document document, ElementId viewId);同样的,这个构造函数,估计是指选中的视图ViewId下的Document对象。

public FilteredElementCollector(Document document, ICollection<ElementId> elementIds);这个就有点不好理解了,由于我没有写过Revit二开的代码,所以,不好说这2个参数之间是什么关系。你看前者是当前文档选中的元素,后一个参数是元素id的集体,难道是二者的交集,又或者是并集?这可能需要实际在代码里操作一遍看一下结果,才知道二者之间的关系了。 

再看这个过滤器的具体方法,会更有意思,从字面上,我们可以看出来,它还提供了类似OfClass、OfCategory、WhereElementIsElementType、WhereElementIsViewIndependent的二次过滤,然后再返回可枚举的结果集合。

通常,每一个可枚举的对象,都会提供一个GetElementIterator()方法,让你直接得到枚举器对象。实际上这是微软框架接口已经定好必须实现的方法。

 那么好,上面说的是这个过滤器可以枚举,这仅仅是得到了集合结果。我们还需要一个枚举器(迭代器)来访问它,那么就用FilteredElementIterator就可以了。他提供了集合数据的访问操作方式,如MoveNext、Reset等。

枚举器有一个很重要的地方,就是他的构造函数是不可以访问的。那么怎么办呢?通过可枚举的类来调用GetElementIterator()方法得到枚举器即可。

原文地址:https://www.cnblogs.com/mazhiyuan/p/13353983.html