Adding more operators with Where as an example ( Query Design continued ):
This post is a part of a series of posts about query design. For the previous post see: https://blogs.msdn.com/vladimirsadov/archive/2007/06/07/query-pattern-composability-query-design-continued.aspx
As you might have seen queries have a lot more operators than just Select. Here we will take a look how we can add support for Where to our queryable type.
It is surprisingly easy to implement Where. Compiler will use any function that is named Where, can be applied to the source collection and takes a delegate function that takes an element of the collection and returns a Boolean result.
I will not do delayed execution tricks in this sample for simplicity (do not want to implement all that IEnumerable support again), however it is fairly trivial to generalize this sample so that both Select and Where are delay-executed.
Class MyGenericQueryable(Of T)
Public elements As IEnumerable(Of T)
Public Function [Select](Of S)(ByVal projection As Func(Of T, S)) As MyGenericQueryable(Of S)
Dim new_col As New MyGenericQueryable(Of S)
Dim new_elements As New List(Of S)
new_col.elements = new_elements
For Each element In elements
new_elements.Add(projection(element))
Next
Return new_col
End Function
Public Function Where(ByVal predicate As Func(Of T, Boolean)) As MyGenericQueryable(Of T)
Dim new_col As New MyGenericQueryable(Of T)
Dim new_elements As New List(Of T)
new_col.elements = new_elements
For Each element In elements
If predicate(element) Then
new_elements.Add(element)
End If
Next
Return new_col
End Function
End Class
Module Module1
Sub Main()
Dim arr As Integer() = New Integer() {1, 2, 3}
Dim col As New MyGenericQueryable(Of Integer)
col.elements = arr
Dim q = From i In col Where i > 1 Select i
For Each t In q.elements
Console.WriteLine(t)
Next
End Sub
End Module