Search Anonymous Type List with Linq

34 Views Asked by At

Is there a better way to find a value in an list of anonymous types? I would like to use linq.

Sub Main()
    Dim listOfAnonymousTypes = {
        New With {.Name = "John", .Age = 30},
        New With {.Name = "Alice", .Age = 25},
        New With {.Name = "Bob", .Age = 28}
    }

    Dim age = FindPersonsAge(listOfAnonymousTypes, "Bob")
End Sub
Function FindPersonsAge(list As Object, name As String) As Integer
    Dim result = Nothing
    For Each p In list
        If p.Name = name Then
            result = p.Age
            Exit For
        End If
    Next
    Return result
End Function
2

There are 2 best solutions below

0
Tim Schmelter On

Yes

Dim age = listOfAnonymousTypes.FirstOrdefault(Function(x) x.Name = "Bob")?.Age

Note that the result is an Integer? because of the null conditional operator. So if there is no "Bob" the result is Nothing. You can use HasValue and Value to get the Integer-value.

0
Enigmativity On

If you put your compiler into Option Strict On mode you'll find that your current VB.Net doesn't compile. It's currently unsafe code relying on dynamic dispatch to work. That just makes it far more likely that you'll write buggy code.

To make your method strongly typed then you need to do this:

Function FindPersonsAge(Of T, R)( _
        list As IEnumerable(Of T), _
        predicate As Func(Of T, Boolean), _
        projection As Func(Of T, R)) As R
    For Each p In list
        If predicate(p) Then
            Return projection(p)
        End If
    Next
End Function

That gets called like this:

Dim age = _
    FindPersonsAge( _
        listOfAnonymousTypes, _
        Function (x) x.Name = "Bob", _
        Function (x) x.Age)

Of course, it's now almost a LINQ query. That would be written like this:

Dim age = _
    listOfAnonymousTypes _
        .Where(Function (x) x.Name = "Bob") _
        .Select(Function (x) x.Age) _
        .FirstOrDefault()

It's probably easier and safer to work with it as LINQ.