集合

大多数Revit Platform API属性和方法在提供对一组相关项的访问时都使用.NET Framework集合类。

在Revit集合类型中实现的IEnumerator和IEnumerator接口在System.Collection命名空间中定义。

Pages in this section 本节中的页面

  • Interface 接口
  • Collections and Iterators 集合和迭代器

Interface 接口

以下各节讨论与接口相关的集合类型。

IEnumerable

IELTS接口位于System.Collections命名空间中。它公开枚举数,该枚举数支持对非泛型集合进行简单迭代。GetEnumerator()方法获取实现此接口的枚举器。返回的IEnumerator对象在整个集合中迭代。GetEnumerator()方法由C#中的foreach循环隐式使用。

IEnumerator

IEnumerator接口位于System.Collections命名空间中。它支持对非泛型集合进行简单迭代。IEnumerator是所有非泛型枚举器的基接口。C#中的foreach语句隐藏了枚举器的复杂性。

注意:建议使用foreach而不是直接操作枚举器。

枚举数用于读取集合数据,但不能用于修改基础集合。使用IEnumerator如下:

  • 最初,枚举数位于集合中第一个元素的前面。但是,最好总是在第一次获取枚举数时调用Reset()。
    • Reset()方法将枚举数移回原始位置。在此位置,调用Current属性将引发异常。
    • 调用MoveNext()方法,在阅读当前迭代器值之前,将枚举器前进到集合的第一个元素。
  • 在调用MoveNext()方法或Reset()方法之前,Current属性返回相同的对象。MoveNext()方法将当前迭代器设置为下一个元素。
  • 如果MoveNext通过了集合的末尾,则枚举数位于集合中最后一个元素之后,MoveNext返回false。
    • 当枚举数处于此位置时,对MoveNext的后续调用也返回false。
    • 如果对MoveNext的最后一次调用返回false,则调用Current属性将引发异常。
    • 要再次将当前迭代器设置为集合中的第一个元素,请调用Reset()方法,然后调用MoveNext()。
  • 只要集合保持不变,枚举数就保持有效。
    • 如果对集合进行了更改(如添加、修改或删除元素),则枚举数将失效,并且下次调用MoveNext()或Reset()方法时将引发InvalidOperationException。
    • 如果在MoveNext和当前迭代器之间修改了集合,则Current属性返回到指定的元素,即使枚举器已经无效。

注意:所有对Reset()方法的调用都必须导致枚举数的相同状态。首选的实现是将枚举数移动到集合的开头,在第一个元素之前。如果在创建枚举数之后修改了集合,则这将使枚举数无效,这与MoveNext()和Current属性一致。

Collections and Iterators 集合和迭代器

在Revit Platform API中,集合和迭代器是通用且类型安全的。

所有集合都实现IEnumerator接口,所有相关迭代器都实现IEnumerator接口。因此,所有方法和属性都在Revit Platform API中实现,并且可以在相关集合中发挥作用。

所有集合的实现都是类似的。下面的示例使用ModelCurveArray演示如何使用主集合属性:

代码区域9-2:使用集合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
UIDocument uidoc = new UIDocument(document); 
ICollection selectedIds = uidoc.Selection.GetElementIds();

// Store the ModelLine references
ModelCurveArray lineArray = new ModelCurveArray();

// … Store operation
Autodesk.Revit.DB.ElementId id = new Autodesk.Revit.DB.ElementId(131943); //assume 131943 is a model line element id
lineArray.Append(document.GetElement(id) as ModelLine);

// use Size property of Array
TaskDialog.Show("Revit","Before Insert: " + lineArray.Size + " in lineArray.");

// use IsEmpty property of Array
if (!lineArray.IsEmpty)
{
// use Item(int) property of Array
ModelCurve modelCurve = lineArray.get_Item(0) as ModelCurve;

// erase the specific element from the set of elements
selectedIds.Remove(modelCurve.Id);

// create a new model line and insert to array of model line
SketchPlane sketchPlane = modelCurve.SketchPlane;

XYZ startPoint = new XYZ(0, 0, 0); // the start point of the line
XYZ endPoint = new XYZ(10, 10, 0); // the end point of the line
// create geometry line
Line geometryLine = Line.CreateBound(startPoint, endPoint);

// create the ModelLine
ModelLine line = document.Create.NewModelCurve(geometryLine, sketchPlane) as ModelLine;

lineArray.Insert(line, lineArray.Size - 1);
}

TaskDialog.Show("Revit","After Insert: " + lineArray.Size + " in lineArray.");

// use the Clear() method to remove all elements in lineArray
lineArray.Clear();

TaskDialog.Show("Revit","After Clear: " + lineArray.Size + " in lineArray.");

注:翻译自Revit API Developers Guide