It's really very simple to get LINQ running with ArcObjects. All you have to do is add an extension method to either ICursor or IFeatureCursor like so:
public static class ICursorExtensions {
public static IEnumerable<IRow> AsEnumerable(this ICursor source) {
Func<IRow> next = () => source.NextRow();
IRow current = next();
while (current != null) {
yield return current;
current = next();
}
}
}
With your new extension method in hand, you can unleash LINQ on your ArcObjects code. You can now write code like this:
Int32 count = cursor.AsEnumerable().Count();
Or, you could write a query expression against two cursor objects:
var resultSeq =
from x in cursor1.AsEnumerable()
from y in cursor2.AsEnumerable()
where x.get_Value(0) = y.get_Value(0)
select new { Left = x, Right = y };
You can do a similar thing in F#:
type ICursor with
member c.AsEnumerable() =
seq {
let next = c.NextRow
let current = ref (next())
while !current <> null do
yield !current
do current := next()
}
let count = cursor.AsEnumerable() |> Seq.length
Sure beats manually manipulating an enumerator, doesn't it?

2 comments:
Love to see a vb.net version. Have trouble with the code conversion.
Unfortunately, there is no direct equivalent to this code in Visual Basic since the language does not support a "yield" operation. But, you can gather all of the rows in a List and pass the list out of the method:
-----------------------------
Imports System.Collections.Generic
Imports System.Runtime.CompilerServices
Public Module ICursorExtensions
<Extension()> _
Public Function AsEnumerable(ByVal source As ICursor) As IEnumerable(Of IRow)
Dim nextRow As Func(Of IRow) = Function() source.NextRow()
Dim rows As New List(Of IRow)
Dim current As IRow = nextRow()
Do While current IsNot Nothing
rows.Add(current)
current = nextRow()
Loop
Return rows
End Function
End Module
-----------------------------
Hope that helps!
Post a Comment