user10479
user10479

Reputation: 810

lambda expressions in vb.net

I have something that is driving me absolutely crazy...

    Public Function GetAccountGroups() As IList(Of AccountGroup)
        Dim raw_account_groups As IList(Of AccountGroup)
        raw_account_groups = _repository.GetAccountGroups().ToList()
        Dim parents = (From ag In raw_account_groups _
                      Where ag.parent_id = 0 _
                      Select ag).ToList()

        parents(0).sub_account_groups = (From sag In raw_account_groups _
                               Where sag.parent_id = 0 _
                                Select sag).ToList()

        Dim sql_func As Func(Of AccountGroup, List(Of AccountGroup)) = Function(p) _
                                                                      (From sag In raw_account_groups _
                                                                       Where sag.parent_id = p.id _
                                                                       Select sag).ToList()

        parents.ForEach(Function(p) p.sub_account_groups = sql_func(p))

        Return parents
    End Function

The line parents.ForEach(Function(p) p.sub_account_groups = sql_func(p)) has this error...

Operator '=' is not defined for types 'System.Collections.Generic.IList(Of st.data.AccountGroup)' and 'System.Collections.Generic.List(Of st.data.AccountGroup)'.

but I really can't see how it is any different from this code from Rob Connery

public IList<Category> GetCategories() {
    IList<Category> rawCategories = _repository.GetCategories().ToList();                 
    var parents = (from c in rawCategories 
        where c.ParentID == 0
        select c).ToList();
     parents.ForEach(p =>
    {
        p.SubCategories = (from subs in rawCategories
        where subs.ParentID == p.ID
        select subs).ToList();
    });

    return parents; 
}

which compiles perfectly... what am I doing incorrectly?

Upvotes: 5

Views: 14082

Answers (5)

Tore Nestenius
Tore Nestenius

Reputation: 19971

I guess ag.parent_id = 0 should be Where ag.parent_id == 0?

Upvotes: 0

BSalita
BSalita

Reputation: 8961

Use Sub for assignment operator:

parents.ForEach(Sub(p) p.sub_account_groups = sql_func(p))

Upvotes: 0

Konrad Rudolph
Konrad Rudolph

Reputation: 546073

The accepted answer here is probably wrong, based on your code. chyne has given the correct clue: lambdas in VB always have return values (unlike in C#), statement lambdas are introduced in the next version though.

In the meantime, you simply can't use this code in VB. Use a regular loop instead:

For Each p In parents
    p.sub_account_groups = sql_func(p)
Next

The next version of VB (available as a Beta since yesterday) would allow the following code to be written:

parents.ForEach(Sub (p) p.sub_account_groups = sql_func(p))

Upvotes: 8

chyne
chyne

Reputation: 667

Lambda's in VB.Net have to return a value, so your equal sign ('=') is being intepreted as a comparison (so that the lambda returns a boolean), rather than an assignment.

Upvotes: 8

Jeff Moser
Jeff Moser

Reputation: 20053

I haven't used VB.NET since moving to C# 3.0, but it seems like it could be a type inference issue. The error is a bit odd since List implements IList, so the assignment should work. You can say "p.ID = 123" for the lambda and things seem to work.

For anyone else interested in looking into it, here is code that you can paste into a new VB.NET console project to demonstrate this issue:

Module Module1
    Sub Main()
    End Sub
End Module

Class AccountGroup
    Public parent_id As Integer
    Public id As Integer
    Public sub_account_groups As List(Of AccountGroup)
End Class
Class AccountRepository
    Private _repository As AccountRepository

    Public Function GetAccountGroups() As IList(Of AccountGroup)
        Dim raw_account_groups As IList(Of AccountGroup)
        raw_account_groups = _repository.GetAccountGroups().ToList()
        Dim parents = (From ag In raw_account_groups _
                       Where ag.parent_id = 0 _
                       Select ag).ToList()
        parents(0).sub_account_groups = (From sag In raw_account_groups _
                                         Where sag.parent_id = 0 _
                                         Select sag).ToList()

        Dim sql_func As Func(Of AccountGroup, List(Of AccountGroup)) = Function(p) _
                                                                            (From sag In raw_account_groups _
                                                                             Where sag.parent_id = p.id _
                                                                             Select sag).ToList()



        parents.ForEach(Function(p) p.sub_account_groups = sql_func(p))
        Return parents
    End Function
 End Class

Upvotes: 0

Related Questions