views:

1283

answers:

4

I have searched high and low for documentation on how to use this feature. While the loop I could write would be simple and take no time, I really would like to learn how to use this.

Basically I have a class, say, Widget, with a Save() sub that returns nothing. So:

Dim w as New Widget()
w.Save()

basically saves the widget. Now let's say I have a generic collection List(Of Widget) name widgetList(Of Widget) and I want to run a Save() on each item in that list. It says I can do a

widgetList.ForEach([enter Action(Of T) here])

....but how in the F does this work??? There is no documentation anywhere on the intrablags. Help would be much much appreciated.

A: 

The below should work although I'm not up to speed on VB.Net so you may need to adjust accordingly.

widgetList.ForEach(w => w.Save())

sipwiz
that's the problem... C# and VB differ a lot on this, so i need the VB syntax.....
Jason
+4  A: 

If you're using VB9 (VS2008) I don't think you'll be able to use an anonymous function easily - as far as I'm aware, anonymous functions in VB9 have to be real functions (i.e. they have to return a value) whereas Action<T> doesn't return anything. C# 2's anonymous methods and C# 3's lambda expressions are more general, which is why you'll see loads of examples using List<T>.ForEach from C# and very few using VB :(

You could potentially write a MakeAction wrapper which takes a Function<T,TResult> and returns an Action<T>, but I suspect other restrictions on VB9 anonymous functions would make this impractical.

The good news is that VB10 has much more anonymous function support. (C#4 and VB10 are gaining each other's features - I believe MS is trying to go for language parity from now on, to a larger extent than before.)

Until then, to use List<T>.ForEach you'll need to write an appropriate Sub and use AddressOf to create a delegate from it. Here's a small example:

Imports System
Imports System.Collections.Generic

Public Class Test

    Shared Sub Main()
        Dim names as New List(Of String)
        names.Add("Jon")
        names.Add("Holly")
        names.ForEach(AddressOf PrintMe)

    End Sub

    Shared Sub PrintMe(ByVal text as String)
        Console.WriteLine(text)
    End Sub

End Class
Jon Skeet
thank you, and thank you for the example! I wish there were a better way than cluttering up my already-growing list of class functions, but this works for now!
Jason
It's not really that practical.. is it?
Filip Ekberg
A: 

Assuming that VB does not support lambda expressions, you can create an instance of the Action(of T) delegate in VB using this syntax:

new Action(Of T)(AddressOf Widget.Save)
1800 INFORMATION
A: 

well, I'm really outdated now... :-) but in VB it's:

widgetList.ForEach(Sub(w) w.Save())

or, more complicated:

widgetList.ForEach(New Action(Of Widged)(Sub(w As Widged) w.Save()))
Sebastian