tags:

views:

380

answers:

1

I want to execute a function on all the objects within a List of objects using LINQ. I know i saw something similar on SO before but after several failed search attempts, i am posting this question

+8  A: 

Try the following if it is actually of type List<T>.

C#

var list = GetSomeList();
list.ForEach( x => SomeMethod(x) );
' Alternatively
list.ForEach(SomeMethod);

VB.Net

Dim list = GetSomeList();
list.ForEach( Function(x) SomeMethod(x) );

Unfortunately .ForEach is only defined on List<T> so it cannot be used on any general IEnumerable<T> type. Although it's easy to code such a function

C#

public static void ForEach<T>(this IEnumerable<T> source, Action<T> del) {
  foreach ( var cur in source ) {
    del(cur);
  }
}

VB.Net

<Extension()> _
Public Shared Sub ForEach(Of T)(source As IEnumerable(Of T), ByVal del As Action(Of T)
  For Each cur in source
    del(cur)
  Next
End Sub

With this you can run .ForEach on any IEnumerable<T> which makes it usable from practically any LINQ query.

var query = from it in whatever where it.SomeProperty > 42;
query.ForEach(x => Log(x));

EDIT

Note to use the .ForEach for VB.Net. You must chose a function that returns a value. It's a limitation of lambda expressions in VB.Net 9 (VS 2009). But there is o work around. Say you want to call SomeMethod which is a Sub. Simply create a wrapper which returns an empty value

Sub SomeMethod(x As String) 
  ... 
End Sub

Function SomeMethodWrapper(x As String)
  SomeMethod(x)
  Return Nothing
End Function

list.ForEach(Function(x) SomeMethod(x)) ' Won't compile
list.ForEach(function(x) SomeMethodWrapper(x)) ' Works
JaredPar
i would like to take the first approach you have mentioned. does that works similarly in vb.net
Vikram
@Vikram, yes you can. I updated the code to include VB.Net samples.
JaredPar
System.Linq already provides an extension for IEnumerable<T> that gives you a .ToList() which you can use, right?
Terry Donaghe
@Terry yes you can take that approach and it will work. But it does force everything into a single in memory collection. Nothing inherently wrong with that but generally people avoid it when using LINQ.
JaredPar
thanks for the adding the snippet, however when i try to use the syntax you have given for vb.net, it does not works. it does not even lets me compile.
Vikram
this is what i tried. and when i try to write SomeMethod(x), it shows me blue underlining saying that "Expression does not produce value". Dim list = GetSomeList()list.ForEach( Function(x) SomeMethod(x) )
Vikram
@Vikram, that's because ForEach is a Sub and returns no value. If you want to modify the items in the list and return a new one, use Select instead of ForEach
JaredPar
i dont want to return any value but simply load some child elements in the object
Vikram
@Vkiram, I see the issue now, will update answer in a sec
JaredPar