views:

330

answers:

5

How would you convert this to VB (using .NET 4.0 / VS2010) ?

bw.DoWork += (o, args) =>
{
     Code Here
};

I thought maybe like this:

AddHandler bw.DoWork,
    Function(o, args)

        Code Here

    End Function

But it says Function does not return a value on all code paths.

Ideas?

+3  A: 

VB.NET lacks this

Interesting bits:

(..)VB does not have anonymous methods, only Lambda expressions (no way to declare an anonymous Action delegate).

Arnis L.
Not what I asked
SLC
They were supposed to be added for .Net 4 but the feature got cut :(
magnifico
@SLC the answer is that in VB.NET you cant use a lambda unless your delegate returns a value. You can use any other kind of delegate. Create a regular sub then use it as your delegate.
magnifico
Of course, d'oh! But if I replace the Function in the code above with Sub, will that sort it?
SLC
@SLC it should sort that. Let us know. :)
Arnis L.
Seems ok, I have to finish converting the entire application before I can run and test it. So does this mean VB.NET *does* support those things? I'm not 100% on all the new stuff, I am just doing blind conversions at the moment.
SLC
It does not support anonymous action delegates. In your case - you just don't need them.
Arnis L.
Replacing the keyword Function with the keyword Sub won't work. It is not supported in VBNET2008. Instead, you need to use a method pointer with the keyword AddressOf Sub, and write yourself a Sub which performs your tasks. In 2010, is was suppose to work though.
Will Marcouiller
Oh.. my mistake - missed 'have to finish to run and test' part. Thought it works already. Got confused at the end of day as usual. Will is right.
Arnis L.
It worked great, thanks. Perhaps I should have said I was using VS2010. Oops.
SLC
+1  A: 

The problem is that we need to know what "Code Here" does. A Function has to return a value (have a Return Statement). If you don't want to return a value, then your Function needs to be a Sub.

Nick
True... Actually - for this case, just changing to Sub (i guess, equivalent in c# would be `Action<T>`) should work. It's more painful with 3rd party libs.
Arnis L.
+2  A: 

You can't make it that way, but you can make it work like:

  Sub New()    
    AddHandler bw.DoWork, AddressOf Stuff    
  End Sub

  Sub Stuff(ByVal o, ByVal args)    
    ' Code Here '   
  End Sub

You are basically adding an event that calls your code and no event returns a value except through the parameters passed into the routine. That makes it a Sub not a Function.

David Parvin
A: 

You don't get multiline lambda's until 2010. If you have to convert multiline in VB9, then you have to do some gyrations, but it can be done. You end up having to create a holder object, set properties on it, then call a shared function, not nearly as elegant as it is in C#

David
A: 

I met something alike when trying to use lambda expressions in VBNET2008.

As the keyword Function is used to indicate to the compiler that a lambda expression is used, the expression must return a value. In this scenario, the use of the keyword Sub would be more appropriate, but it is not possible yet in VBNET2008.

VBNET2010 should address this by allowing Subs within lambda expressions.

Here's an example of workaround that worked great for me at this question on SO: What would be the equivalent VB.NET code for this C#...

In short, instead of writing your lambda expression into the core of your method, you need to point the Sub you wish to perform the work with using the AddressOf Sub.

David Parvin did also write the workaround exactly as you need it.

EDIT:

You could always opt for the delegate solution. Private Delegate Sub MyMethodAsync()

Public Sub Button1_Click(...) Handles Button1.Click
    Dim myMethodAsync As MyMethodAsync = AddressOf MyDoWorkAsync

    _myBackgroundWorker.RunWorkerAsync(myMethodAsync)
    Dim loadingForm = New LoadingForm()
    loadingForm.ShowDialog()
End Sub

Private Sub _myBackgroundWorker_DoWork([parameters here...]) Handles _myBackgroundWorker.DoWork
    ' Do some stuff...
End Sub

I know it ain't anonymous method, thus you might have a real hard time trying to work this way in VBNET, even 2008. Such features are supposed to be part of VBNET2010, but I think they cut it out, but I'm really not sure enough to confirm it firmly.

Hope this helps!

Will Marcouiller