[Resolved] C# to VB Adaption Problem with Lambda Expressions
-
Hi guys, I hope you had a nice start into 2012! I've been trying to convert this^ piece of code into VB, using VS Express 2010 and #Develop. In order to avoid problems with conversion of c# 'yield' operator, I put the extensions into a DLL and set a reference to that. The translated code of the test implementation reads like:
Shared Sub Main(ByVal args() As String)
Dim worker As New BackgroundWorker()
worker.WorkerReportsProgress = True
AddHandler worker.DoWork, Function(sender, e)
' pretend we have a collection of items to process
Dim items(999) As Integer
items.WithProgressReporting(Function(progress) worker.ReportProgress(progress)).ForEach(Function(item) Thread.Sleep(10)) ' simulate some real work
End FunctionAddHandler worker.ProgressChanged, Function(sender, e) ' make sure the figure is written to the ' same point on screen each time Console.SetCursorPosition(1, 0) Console.Write(e.ProgressPercentage) End Function worker.RunWorkerAsync() Console.Read()
End Sub
Unfortunately in VB the line
items.WithProgressReporting(Function(progress) worker.ReportProgress(progress).ForEach(Function(item) Thread.Sleep(10)))
throws an exception "Expression does not produce a value" at the underlined place. There's no such exception in C# where the test code compiles and executes fine. Having to implement the technique into my VB application, I'd like to understand where the problem arises. Could anyone of you tell me what's wrong in the (automatic) translation of the Lambda expression? Thank you Mick
-
Hi guys, I hope you had a nice start into 2012! I've been trying to convert this^ piece of code into VB, using VS Express 2010 and #Develop. In order to avoid problems with conversion of c# 'yield' operator, I put the extensions into a DLL and set a reference to that. The translated code of the test implementation reads like:
Shared Sub Main(ByVal args() As String)
Dim worker As New BackgroundWorker()
worker.WorkerReportsProgress = True
AddHandler worker.DoWork, Function(sender, e)
' pretend we have a collection of items to process
Dim items(999) As Integer
items.WithProgressReporting(Function(progress) worker.ReportProgress(progress)).ForEach(Function(item) Thread.Sleep(10)) ' simulate some real work
End FunctionAddHandler worker.ProgressChanged, Function(sender, e) ' make sure the figure is written to the ' same point on screen each time Console.SetCursorPosition(1, 0) Console.Write(e.ProgressPercentage) End Function worker.RunWorkerAsync() Console.Read()
End Sub
Unfortunately in VB the line
items.WithProgressReporting(Function(progress) worker.ReportProgress(progress).ForEach(Function(item) Thread.Sleep(10)))
throws an exception "Expression does not produce a value" at the underlined place. There's no such exception in C# where the test code compiles and executes fine. Having to implement the technique into my VB application, I'd like to understand where the problem arises. Could anyone of you tell me what's wrong in the (automatic) translation of the Lambda expression? Thank you Mick
Seems to me one of your right parentheses is not at the correct position; you need one more before
ForEach
. :)Luc Pattyn [My Articles] Nil Volentibus Arduum
-
Seems to me one of your right parentheses is not at the correct position; you need one more before
ForEach
. :)Luc Pattyn [My Articles] Nil Volentibus Arduum
-
Hi guys, I hope you had a nice start into 2012! I've been trying to convert this^ piece of code into VB, using VS Express 2010 and #Develop. In order to avoid problems with conversion of c# 'yield' operator, I put the extensions into a DLL and set a reference to that. The translated code of the test implementation reads like:
Shared Sub Main(ByVal args() As String)
Dim worker As New BackgroundWorker()
worker.WorkerReportsProgress = True
AddHandler worker.DoWork, Function(sender, e)
' pretend we have a collection of items to process
Dim items(999) As Integer
items.WithProgressReporting(Function(progress) worker.ReportProgress(progress)).ForEach(Function(item) Thread.Sleep(10)) ' simulate some real work
End FunctionAddHandler worker.ProgressChanged, Function(sender, e) ' make sure the figure is written to the ' same point on screen each time Console.SetCursorPosition(1, 0) Console.Write(e.ProgressPercentage) End Function worker.RunWorkerAsync() Console.Read()
End Sub
Unfortunately in VB the line
items.WithProgressReporting(Function(progress) worker.ReportProgress(progress).ForEach(Function(item) Thread.Sleep(10)))
throws an exception "Expression does not produce a value" at the underlined place. There's no such exception in C# where the test code compiles and executes fine. Having to implement the technique into my VB application, I'd like to understand where the problem arises. Could anyone of you tell me what's wrong in the (automatic) translation of the Lambda expression? Thank you Mick
-
Michael Schäuble wrote:
I'd like to understand where the problem arises. Could anyone of you tell me what's wrong in the (automatic) translation of the Lambda expression?
Where is the original C# code?
Bastard Programmer from Hell :suss:
-
In my initial message "this" is a link to the code (it should appear written in blue?). But it leads to the "Functional Fun" code which YOU yourself had recommended :-D in my LINQ-to-SQL question yesterday ;)
-
I'm afraid I don't understand what you mean? Anyway, here's the link ^ again
-
I'm afraid I don't understand what you mean? Anyway, here's the link ^ again
Michael Schäuble wrote:
I'm afraid I don't understand what you mean
My bad, I thought you were talking about another URL and that it got mixed up. Still recovering from the old year. Translators don't like lamda's, so you might take that one out before converting the code. Would result in something like below;
AddHandler worker.ProgressChanged, AddressOf ProgressChanged worker.RunWorkerAsync() Console.Read()
End Sub
Public Sub ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs)
' make sure the figure is written to the
' same point on screen each time
Console.SetCursorPosition(1, 0)
Console.Write(e.ProgressPercentage)
End SubBastard Programmer from Hell :suss:
-
Michael Schäuble wrote:
I'm afraid I don't understand what you mean
My bad, I thought you were talking about another URL and that it got mixed up. Still recovering from the old year. Translators don't like lamda's, so you might take that one out before converting the code. Would result in something like below;
AddHandler worker.ProgressChanged, AddressOf ProgressChanged worker.RunWorkerAsync() Console.Read()
End Sub
Public Sub ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs)
' make sure the figure is written to the
' same point on screen each time
Console.SetCursorPosition(1, 0)
Console.Write(e.ProgressPercentage)
End SubBastard Programmer from Hell :suss:
Ah, I've been trying that one for another reason: Most of my code is still in VB2008 which doesn't like multi-line lambdas anyway. The whole test procedure looks like this right now:
Public Sub TestProgressReporting() worker = New BackgroundWorker() worker.WorkerReportsProgress = True AddHandler worker.DoWork, AddressOf DoWork AddHandler worker.ProgressChanged, AddressOf ProgressChanged worker.RunWorkerAsync() Console.Read() End Sub Private Sub DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Dim items(999) As Integer items.WithProgressReporting(AddressOf ReportProgress) ' simulate some real work End Sub Private Function ReportProgress() As Integer worker.ReportProgress(progress).ForEach(Function(item) Thread.Sleep(10)) End Function Private Sub ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) 'worker.ReportProgress() ' make sure the figure is written to the ' same point on screen each time Console.SetCursorPosition(1, 0) Console.Write(e.ProgressPercentage) End Sub
It still won't compile because 'progress' (underlined) is unknown.
-
Ah, I've been trying that one for another reason: Most of my code is still in VB2008 which doesn't like multi-line lambdas anyway. The whole test procedure looks like this right now:
Public Sub TestProgressReporting() worker = New BackgroundWorker() worker.WorkerReportsProgress = True AddHandler worker.DoWork, AddressOf DoWork AddHandler worker.ProgressChanged, AddressOf ProgressChanged worker.RunWorkerAsync() Console.Read() End Sub Private Sub DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Dim items(999) As Integer items.WithProgressReporting(AddressOf ReportProgress) ' simulate some real work End Sub Private Function ReportProgress() As Integer worker.ReportProgress(progress).ForEach(Function(item) Thread.Sleep(10)) End Function Private Sub ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) 'worker.ReportProgress() ' make sure the figure is written to the ' same point on screen each time Console.SetCursorPosition(1, 0) Console.Write(e.ProgressPercentage) End Sub
It still won't compile because 'progress' (underlined) is unknown.
Progress doesn't take a parameter, according to it's declaration. How did you resolve the fact that VB.NET lacks a "yield return" statement? ..and how about simply wrapping the C# code in an assembly and reference that from VB?
Bastard Programmer from Hell :suss:
-
Progress doesn't take a parameter, according to it's declaration. How did you resolve the fact that VB.NET lacks a "yield return" statement? ..and how about simply wrapping the C# code in an assembly and reference that from VB?
Bastard Programmer from Hell :suss:
From my initial message:
Michael Schäuble wrote:
In order to avoid problems with conversion of c# 'yield' operator, I put the extensions into a DLL and set a reference to that.
According to IntelliSense 'progress' should be an integer value for 'percentProgress'. The funny thing is that it works as described as long as I stay in C# with the Main procedure - also when using the same referenced DLL for all the extensions:
items .WithProgressReporting(progress => worker.ReportProgress(progress)) .ForEach(item => Thread.Sleep(10)); // simulate some real work
Line 2 results in the percentage, which is properly reported to the console. So there really must be something wrong with the lambda, which obviously is too cryptic for me... Still this is exactly the part of the code which I can't reference (main procedure "TestProgressReporting") since my application is written in VB.
-
Progress doesn't take a parameter, according to it's declaration. How did you resolve the fact that VB.NET lacks a "yield return" statement? ..and how about simply wrapping the C# code in an assembly and reference that from VB?
Bastard Programmer from Hell :suss:
Eddy Vluggen wrote:
How did you resolve the fact that VB.NET lacks a "yield return" statement?
perhaps with patience. Yield exists since VS2010 SP1 according to this[^]. And it is simply
yield
, notyield return
, so for once VB.NET is less verbose than C#. :)Luc Pattyn [My Articles] Nil Volentibus Arduum
-
Eddy Vluggen wrote:
How did you resolve the fact that VB.NET lacks a "yield return" statement?
perhaps with patience. Yield exists since VS2010 SP1 according to this[^]. And it is simply
yield
, notyield return
, so for once VB.NET is less verbose than C#. :)Luc Pattyn [My Articles] Nil Volentibus Arduum
Hey Luc, thanks for the hint, I'm just about downloading SP1. Still I'm afraid it wouldn't solve the problem I have: As I wrote I put all the extensions into a DLL which I'm referencing from my main VB code as well as from VB and C# test procedures. It seems pretty clear that there must be something wrong with the Lambda expressions. Would you have a look at them, please?
-
Hey Luc, thanks for the hint, I'm just about downloading SP1. Still I'm afraid it wouldn't solve the problem I have: As I wrote I put all the extensions into a DLL which I'm referencing from my main VB code as well as from VB and C# test procedures. It seems pretty clear that there must be something wrong with the Lambda expressions. Would you have a look at them, please?
I seldom use lambda's, I probably can't help you. If they are in a separate DLL, why aren't you using C# for them? :)
Luc Pattyn [My Articles] Nil Volentibus Arduum
-
I seldom use lambda's, I probably can't help you. If they are in a separate DLL, why aren't you using C# for them? :)
Luc Pattyn [My Articles] Nil Volentibus Arduum
You misunderstood me. All the extension methods, which contain the C# 'yield' operator, are in a separate DLL. My application is in VB so I have to call the extensions from VB using adapted code... and the sample code (pls. see link in the initial message) is in C# where the Lambdas work.
-
Eddy Vluggen wrote:
How did you resolve the fact that VB.NET lacks a "yield return" statement?
perhaps with patience. Yield exists since VS2010 SP1 according to this[^]. And it is simply
yield
, notyield return
, so for once VB.NET is less verbose than C#. :)Luc Pattyn [My Articles] Nil Volentibus Arduum
-
Hi guys, I hope you had a nice start into 2012! I've been trying to convert this^ piece of code into VB, using VS Express 2010 and #Develop. In order to avoid problems with conversion of c# 'yield' operator, I put the extensions into a DLL and set a reference to that. The translated code of the test implementation reads like:
Shared Sub Main(ByVal args() As String)
Dim worker As New BackgroundWorker()
worker.WorkerReportsProgress = True
AddHandler worker.DoWork, Function(sender, e)
' pretend we have a collection of items to process
Dim items(999) As Integer
items.WithProgressReporting(Function(progress) worker.ReportProgress(progress)).ForEach(Function(item) Thread.Sleep(10)) ' simulate some real work
End FunctionAddHandler worker.ProgressChanged, Function(sender, e) ' make sure the figure is written to the ' same point on screen each time Console.SetCursorPosition(1, 0) Console.Write(e.ProgressPercentage) End Function worker.RunWorkerAsync() Console.Read()
End Sub
Unfortunately in VB the line
items.WithProgressReporting(Function(progress) worker.ReportProgress(progress).ForEach(Function(item) Thread.Sleep(10)))
throws an exception "Expression does not produce a value" at the underlined place. There's no such exception in C# where the test code compiles and executes fine. Having to implement the technique into my VB application, I'd like to understand where the problem arises. Could anyone of you tell me what's wrong in the (automatic) translation of the Lambda expression? Thank you Mick
VB2010 has introduced sub(parameter) into the lambda specification. I haven't tested it but wouldn't the following work?
items.WithProgressReporting(sub(progress) worker.ReportProgress(progress) end sub).forEach(function(item) thread.Sleep(10)))
Lobster Thermidor aux crevettes with a Mornay sauce, served in a Provençale manner with shallots and aubergines, garnished with truffle pate, brandy and a fried egg on top and Spam - Monty Python Spam Sketch
-
Hi guys, I hope you had a nice start into 2012! I've been trying to convert this^ piece of code into VB, using VS Express 2010 and #Develop. In order to avoid problems with conversion of c# 'yield' operator, I put the extensions into a DLL and set a reference to that. The translated code of the test implementation reads like:
Shared Sub Main(ByVal args() As String)
Dim worker As New BackgroundWorker()
worker.WorkerReportsProgress = True
AddHandler worker.DoWork, Function(sender, e)
' pretend we have a collection of items to process
Dim items(999) As Integer
items.WithProgressReporting(Function(progress) worker.ReportProgress(progress)).ForEach(Function(item) Thread.Sleep(10)) ' simulate some real work
End FunctionAddHandler worker.ProgressChanged, Function(sender, e) ' make sure the figure is written to the ' same point on screen each time Console.SetCursorPosition(1, 0) Console.Write(e.ProgressPercentage) End Function worker.RunWorkerAsync() Console.Read()
End Sub
Unfortunately in VB the line
items.WithProgressReporting(Function(progress) worker.ReportProgress(progress).ForEach(Function(item) Thread.Sleep(10)))
throws an exception "Expression does not produce a value" at the underlined place. There's no such exception in C# where the test code compiles and executes fine. Having to implement the technique into my VB application, I'd like to understand where the problem arises. Could anyone of you tell me what's wrong in the (automatic) translation of the Lambda expression? Thank you Mick
Try changing this line:
items.WithProgressReporting(Function(progress)
worker.ReportProgress(progress)).ForEach(Function(item) Thread.Sleep(10)) ' simulate some real workTo this:
items.WithProgressReporting(Function(progress) _
worker.ReportProgress(progress)).ToList.ForEach(Function(item) Thread.Sleep(10)) ' simulate some real workThe .ForEach extension method doesn't work with IEnumerables and since that's what WithProgressReporting returns, the resultset must first be cast as a Generic List. Also, I don't know for sure, but it looks like the converter inserted an extra line break. That's why I added the underscore to the end of the first line.
-
Hi guys, I hope you had a nice start into 2012! I've been trying to convert this^ piece of code into VB, using VS Express 2010 and #Develop. In order to avoid problems with conversion of c# 'yield' operator, I put the extensions into a DLL and set a reference to that. The translated code of the test implementation reads like:
Shared Sub Main(ByVal args() As String)
Dim worker As New BackgroundWorker()
worker.WorkerReportsProgress = True
AddHandler worker.DoWork, Function(sender, e)
' pretend we have a collection of items to process
Dim items(999) As Integer
items.WithProgressReporting(Function(progress) worker.ReportProgress(progress)).ForEach(Function(item) Thread.Sleep(10)) ' simulate some real work
End FunctionAddHandler worker.ProgressChanged, Function(sender, e) ' make sure the figure is written to the ' same point on screen each time Console.SetCursorPosition(1, 0) Console.Write(e.ProgressPercentage) End Function worker.RunWorkerAsync() Console.Read()
End Sub
Unfortunately in VB the line
items.WithProgressReporting(Function(progress) worker.ReportProgress(progress).ForEach(Function(item) Thread.Sleep(10)))
throws an exception "Expression does not produce a value" at the underlined place. There's no such exception in C# where the test code compiles and executes fine. Having to implement the technique into my VB application, I'd like to understand where the problem arises. Could anyone of you tell me what's wrong in the (automatic) translation of the Lambda expression? Thank you Mick
I always have trouble with anonymous delegates in VB so I factored them out :
Class Program
Shared worker As BackgroundWorker
Public Shared Sub Main() 'ByVal args As String())
worker = New BackgroundWorker()
worker.WorkerReportsProgress = True
AddHandler worker.DoWork, AddressOf DoWork
AddHandler worker.ProgressChanged, AddressOf ProgressChanged
worker.RunWorkerAsync()
Console.Read()
End SubPrivate Shared Sub DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Dim items = Enumerable.Range(1, 1000) items.WithProgressReporting(AddressOf ReportProgress).ForEach(AddressOf DoSleep) End Sub Private Shared Sub ReportProgress(ByVal progress As Integer) worker.ReportProgress(progress) End Sub Private Shared Sub DoSleep(ByVal item As Integer) Thread.Sleep(10) End Sub Private Shared Sub ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Console.SetCursorPosition(1, 0) Console.Write(e.ProgressPercentage) End Sub
End Class
Cheers
-
Eddy Vluggen wrote:
How did you resolve the fact that VB.NET lacks a "yield return" statement?
perhaps with patience. Yield exists since VS2010 SP1 according to this[^]. And it is simply
yield
, notyield return
, so for once VB.NET is less verbose than C#. :)Luc Pattyn [My Articles] Nil Volentibus Arduum
Hey just wanted to say thanks Luc that link got me to several other links on the subject and could prove quite useful to me in the very near future. Thanks again. This is now supported in VS 2010 SP1, with the Async CTP, see: http://msdn.microsoft.com/en-us/vstudio/gg497937[^] Also see: http://www.microsoft.com/downloads/en/details.aspx?FamilyID=4738205d-5682-47bf-b62e-641f6441735b&displaylang=en[^]
"If you think it's expensive to hire a professional to do the job, wait until you hire an amateur." - Red Adair