2008-09-15 40 views
5

que tengo algo que me está volviendo absolutamente loco ...expresiones lambda en vb.net

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 

La línea "parents.ForEach (function (p) = p.sub_account_groups sql_func (p))" ha este error ...

El operador '=' no está definido para los tipos 'System.Collections.Generic.IList (Of st.data.AccountGroup)' y 'System.Collections.Generic.List (Of st.data. AccountGroup) '.

pero realmente no puedo ver cómo es diferente de este código de 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; 
} 

que compila perfectamente ... ¿qué estoy haciendo mal?

+0

"lambada expressions" - lol :) –

+0

¡Es el código prohibido! –

+0

¿Código prohibido? Pensé que era Ruby? – GEOCHET

Respuesta

0

No he usado VB.NET desde que cambié a C# 3.0, pero parece que podría ser un problema de inferencia de tipo. El error es un poco extraño ya que List implementa IList, por lo que la tarea debería funcionar. Puedes decir "p.ID = 123" para la lambda y las cosas parecen funcionar.

Para cualquier persona interesada en mirar en él, aquí es el código que puede pegar en un nuevo proyecto de consola VB.NET para demostrar este problema:

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 
0

supongo ag.parent_id = 0 debería ser Dónde ag.parent_id == 0?

+0

No en VB ... = es correcto. –

8

Lambda en VB.Net tienen que devolver un valor, por lo que su signo igual ('=') se interpreta como una comparación (para que la lambda devuelva un booleano), en lugar de una asignación.

+0

chyne es correcto. Tu código funcionaría bien en C#. Hice un ejemplo similar para probarlo. Además, no puede tener varias líneas, por lo que ni siquiera puede agregar un Retorno. Entonces debes usar un bucle ForEach. –

8

La respuesta aceptada aquí es probablemente incorrecta, en función de su código. chyne ha dado la pista correcta: las lambdas en VB siempre tienen valores de retorno (a diferencia de C#), sin embargo, en la próxima versión se introducen las lambdas.

Mientras tanto, simplemente no puede usar este código en VB. Utilizar un bucle regular en lugar:

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

La próxima versión de VB (disponible como Beta desde ayer) permitiría el código siguiente para ser escrito:

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

Necesita el EndSub ¿no es así? ¿O lo eliminaron en Beta1? –

+0

@Auxon: no es necesario para frases simples como las anteriores. Al menos, no solías Todavía no he probado la versión beta: estoy usando OS X. –

0

Uso Sub de operador de asignación:

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