How to Filter a Generic List

Generics are a great new feature of .NET 2.0 that still has some enough mystery that not many are actually leveraging this great new set of collection classes.  Real quick, Generics are a templated set of collection classes that are a little thinner than a CollectionBase and a little more powerful than and ArrayList.  One of my first cautions was how do you filter a generic.  The solution I found was the use of the FindAll method, but I think it is a little clunky, and I think the same is true for sorting, but more on that later.

List is the core Generic Class and is in the format of List(Of Object).  The List class has several included methods, several handle the filtering and sorting functionality, in this example I will demonstrate FindAll.

I am going to create a list of Car Makes and Models from my database.

'**** NOTE THIS EXAMPLE USES Extreme Web Works Core Data Acess Framework ****

    Public Function GetModelList() As List(Of ModelsInfo)

        Dim dr As SqlDataReader = ExecuteReader("spGetModelss")

        Dim ml As New List(Of ModelsInfo)

        While dr.Read

           'BindModelInfo is a method that takes a SQLDataReader and creates a ModelInfo class to represent the data object for a Car Model


        End While


        Return ml

    End Function

Once you have your list then you need to define a Delegate Method that will be used to filter your objects in the list.  This method needs to be in either the class that will be manipulating your list or a wrapper class that will handle the functionality of your Generic List.

Public Class ModelList

    Public ml As List(Of ModelsInfo)
    Private Shared _MakeId As String = String.empty

    Public Function GetModelsByMake(ByVal MakeId As String) As List(Of ModelsInfo)

        'Since we can not pass the Makeid in the method we need to set the class variable
        _MakeId = MakeId

        Return ml.FindAll(AddressOf ModelByMake)

    End Function

    ' Search predicate returns true if a .MakeId = MakeId.
    Private Shared Function ModelByMake(ByVal mi As ModelsInfo) _
        As Boolean

        If mi.MakeId = _MakeId Then
            Return True
            Return False
        End If

    End Function

End Class

Notice that I defined a shared member, MakeId to hold the MakeId that we will be filtering.  First I had to make it shared because the delgate method 'ModelByMake' is a shared method.  ModelByMake is a shared function that returns a Boolean, meaning that the Object, ModelsInfo, meets our criteria, Make in this case.  This method calls the List or models we set in our ModelList class.  You need to think of the ModelList as a class that offers the extended functionality of the List class we are using. 

The List class method FindAll has one parameter, a delegate method that will perform the filtering and return a Boolean Value.  The delegate method takes one parameter, the Object class that your List is composed.  The FindAll method passes each one of the Objects (ModelsInfo in our example) and will add the ones that meet our criteria to the List that is returned.

So if we want to define a method to bind all the Dodge models to a GridView it would look like this:

public sub BindDodges

        Dim mc As New ModelsController
        Dim ml As List(Of ModelsInfo) = mc.GetModelList
        Dim mlc As New ModelList = ml
        Dim ml2 As List(Of ModelsInfo) = mlc.GetModelsByMake("DODGE")

        GridView1.DataSource = ml2

end sub 

Of course you can set this up to pass Makes as a variable to the BindMethod and open it to more flexibility, so that is your homework assignment.

Share This Article With Your Friends!