IIRC, .Net 4.0 будет иметь метод расширения .Zip()
для IEnumerable, который уже делает это.
Между тем, не так сложно построить свой собственный. Удивительно, но в то время как несколько других ответов были очень близки, у всех них есть по крайней мере одна проблема. Надеюсь, они будут исправлены. Между тем, это должно делать то, что вы хотите, в VB.Net, со строго типизированными перечислителями, используя правильное сравнение для неизвестных типов и правильно распоряжаться перечислителями:
Using xe As IEnumerator(Of X) = List1.GetEnumerator(), _
ye As IEnumerator(Of Y) = List2.GetEnumerator()
While xe.MoveNext() AndAlso ye.MoveNext()
If xe.Current.Equals(ye.Current) Then
''// do something
End If
End While
End Using
А теперь давайте поместим это в функцию, которой вы можете передать своих собственных делегатов:
Public Shared Sub ZipAction(Of X, Y)(ByVal source1 As IEnumerable(Of X), ByVal source2 As IEnumerable(Of Y), _
ByVal compare As Func(Of X, Y, Boolean), Byval OnEquals As Action(Of X, Y))
Using xe As IEnumerator(Of X) = source1.GetEnumerator(), _
ye As IEnumerator(Of Y) = source2.GetEnumerator()
While xe.MoveNext() AndAlso ye.MoveNext()
If compare(xe.Current, ye.Current) Then
OnEquals(xe.Current, ye.Current)
End If
End While
End Using
End Sub
И, наконец, поскольку эти типы делегатов недоступны до .Net 3.5, вы можете легко объявить их в .Net 2.0 следующим образом:
Public Delegate Sub Action(Of T1, T2) ( _
arg1 As T1, _
arg2 As T2 _
)
Public Delegate Function Func(Of T1, T2, TResult) ( _
arg1 As T1, _
arg2 As T2, _
) As TResult
Чтобы использовать этот код, вы должны сделать что-то вроде этого:
Public Class X
Public Item As String
''//...
End Class
Public Class Y
Public Item As String
''//...
End Class
Public Class Test
Private Function CompareXtoY(ByVal arg1 As X, ByVal arg2 As Y) As Boolean
Return arg1.Item = arg2.Item
End Function
Private Sub OnList1ItemMatchesList2Item(ByVal arg1 As X, ByVal arg2 As Y)
''// Do something...
End Sub
Private list1 As List(Of X) = GetXList()
Private list2 As List(Of Y) = GetYList()
Public Sub TestZip()
ZipAction(list1, list2, AddressOf CompareXtoY, AddressOf OnList1ItemMatchesList2Item)
End Sub
End Class
Если бы это был C #, я бы имел функцию, являющуюся блоком итератора, и "возвращал бы результат" каждой соответствующей паре, вместо того, чтобы просить вас передать делегат Action.