Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Visual Basic
  4. [Resolved] C# to VB Adaption Problem with Lambda Expressions

[Resolved] C# to VB Adaption Problem with Lambda Expressions

Scheduled Pinned Locked Moved Visual Basic
csharplinqhtmlvisual-studiofunctional
28 Posts 8 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Luc Pattyn

    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, not yield return, so for once VB.NET is less verbose than C#. :)

    Luc Pattyn [My Articles] Nil Volentibus Arduum

    L Offline
    L Offline
    Lost User
    wrote on last edited by
    #16

    Cool - I never missed the statement in VB, until this question popped up :)

    Bastard Programmer from Hell :suss:

    1 Reply Last reply
    0
    • S Sonhospa

      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 Function

      AddHandler 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

      S Offline
      S Offline
      Simon_Whale
      wrote on last edited by
      #17

      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

      S 1 Reply Last reply
      0
      • S Sonhospa

        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 Function

        AddHandler 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

        U Offline
        U Offline
        User 7825588
        wrote on last edited by
        #18

        Try changing this line:

        items.WithProgressReporting(Function(progress)
        worker.ReportProgress(progress)).ForEach(Function(item) Thread.Sleep(10)) ' simulate some real work

        To this:

        items.WithProgressReporting(Function(progress) _
        worker.ReportProgress(progress)).ToList.ForEach(Function(item) Thread.Sleep(10)) ' simulate some real work

        The .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.

        S 1 Reply Last reply
        0
        • S Sonhospa

          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 Function

          AddHandler 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

          E Offline
          E Offline
          Estys
          wrote on last edited by
          #19

          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 Sub

          Private 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

          S 1 Reply Last reply
          0
          • L Luc Pattyn

            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, not yield return, so for once VB.NET is less verbose than C#. :)

            Luc Pattyn [My Articles] Nil Volentibus Arduum

            T Offline
            T Offline
            Terence Wallace
            wrote on last edited by
            #20

            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

            1 Reply Last reply
            0
            • S Sonhospa

              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 Function

              AddHandler 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

              D Offline
              D Offline
              DavidSherwood
              wrote on last edited by
              #21

              In VB, a function that returns void is a "Sub". This is true with lambda function as well. So your ForEach lambda should be

              ForEach(Sub(item) Thread.Sleep(10))

              S S 2 Replies Last reply
              0
              • D DavidSherwood

                In VB, a function that returns void is a "Sub". This is true with lambda function as well. So your ForEach lambda should be

                ForEach(Sub(item) Thread.Sleep(10))

                S Offline
                S Offline
                Simon_Whale
                wrote on last edited by
                #22

                Only true with 2010 though, as there is many time I would loved to of used it in my current project that is 3.5 framework

                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

                1 Reply Last reply
                0
                • S Simon_Whale

                  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

                  S Offline
                  S Offline
                  Sonhospa
                  wrote on last edited by
                  #23

                  Hi Simon, sorry for the late response which was due to a short holiday of mine. Thanks for your hint which pushed me in the right direction: In the end, all I had to do was change "function" into "sub" in VB. It's finally solved now, and the line

                  items.WithProgressReporting(Sub(progress) worker.ReportProgress(progress)).ForEach(Sub(item) Thread.Sleep(10))

                  works, as well as Estys suggestion to factor out the subs. No "end" needed here. Regards - Mick

                  S 1 Reply Last reply
                  0
                  • S Sonhospa

                    Hi Simon, sorry for the late response which was due to a short holiday of mine. Thanks for your hint which pushed me in the right direction: In the end, all I had to do was change "function" into "sub" in VB. It's finally solved now, and the line

                    items.WithProgressReporting(Sub(progress) worker.ReportProgress(progress)).ForEach(Sub(item) Thread.Sleep(10))

                    works, as well as Estys suggestion to factor out the subs. No "end" needed here. Regards - Mick

                    S Offline
                    S Offline
                    Simon_Whale
                    wrote on last edited by
                    #24

                    Glad it helped :thumbsup:

                    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

                    1 Reply Last reply
                    0
                    • U User 7825588

                      Try changing this line:

                      items.WithProgressReporting(Function(progress)
                      worker.ReportProgress(progress)).ForEach(Function(item) Thread.Sleep(10)) ' simulate some real work

                      To this:

                      items.WithProgressReporting(Function(progress) _
                      worker.ReportProgress(progress)).ToList.ForEach(Function(item) Thread.Sleep(10)) ' simulate some real work

                      The .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.

                      S Offline
                      S Offline
                      Sonhospa
                      wrote on last edited by
                      #25

                      Hi Member... ;) , sorry for the late response which was due to a short holiday of mine. Thanks for your hint which unfortunately didn't work: In the end, all I had to do was change "function" into "sub" in VB. It's finally solved now, and the line

                      items.WithProgressReporting(Sub(progress) worker.ReportProgress(progress)).ForEach(Sub(item) Thread.Sleep(10))

                      works, as well as Estys suggestion to factor out the subs (no "end" or "ToList" constructions needed). Regards - Mick

                      1 Reply Last reply
                      0
                      • E Estys

                        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 Sub

                        Private 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

                        S Offline
                        S Offline
                        Sonhospa
                        wrote on last edited by
                        #26

                        Hi Estys, sorry for the late response which was due to a short holiday of mine. Thanks for your hint which, together with the other guys' ideas, pushed me in the right direction: In the end, all I had to do was change "function" into "sub" in VB. It's finally solved now, and the line

                        items.WithProgressReporting(Sub(progress) worker.ReportProgress(progress)).ForEach(Sub(item) Thread.Sleep(10))

                        works, as well as your suggestion to factor out the subs. Just to complete: In your snippet I had to change the definition of 'items' to:

                        Dim items As IEnumerable(Of Integer) = Enumerable.Range(1, 1000)

                        in VB. But the most important thing: It works - and I hope I understand it a little better ;) Thanks again, regards - Mick

                        E 1 Reply Last reply
                        0
                        • D DavidSherwood

                          In VB, a function that returns void is a "Sub". This is true with lambda function as well. So your ForEach lambda should be

                          ForEach(Sub(item) Thread.Sleep(10))

                          S Offline
                          S Offline
                          Sonhospa
                          wrote on last edited by
                          #27

                          Hi David, sorry for the late response which was due to a short holiday of mine. Thanks for your hint which pushed me in the right direction: In the end, all I had to do was simply change "function" into "sub" in VB. It's finally solved now, and the line

                          items.WithProgressReporting(Sub(progress) worker.ReportProgress(progress)).ForEach(Sub(item) Thread.Sleep(10))

                          works, as well as Estys suggestion to factor out the subs (slightly changed). Thanks again, regards - Mick

                          1 Reply Last reply
                          0
                          • S Sonhospa

                            Hi Estys, sorry for the late response which was due to a short holiday of mine. Thanks for your hint which, together with the other guys' ideas, pushed me in the right direction: In the end, all I had to do was change "function" into "sub" in VB. It's finally solved now, and the line

                            items.WithProgressReporting(Sub(progress) worker.ReportProgress(progress)).ForEach(Sub(item) Thread.Sleep(10))

                            works, as well as your suggestion to factor out the subs. Just to complete: In your snippet I had to change the definition of 'items' to:

                            Dim items As IEnumerable(Of Integer) = Enumerable.Range(1, 1000)

                            in VB. But the most important thing: It works - and I hope I understand it a little better ;) Thanks again, regards - Mick

                            E Offline
                            E Offline
                            Estys
                            wrote on last edited by
                            #28

                            Michael Schäuble wrote:

                            I had to change the definition of 'items'

                            That's odd, with me it worked as I posted it. I'm on .NET 3.5, VB Express 2008 Cheers

                            If you can read this, you don't have Papyrus installed

                            1 Reply Last reply
                            0
                            Reply
                            • Reply as topic
                            Log in to reply
                            • Oldest to Newest
                            • Newest to Oldest
                            • Most Votes


                            • Login

                            • Don't have an account? Register

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • World
                            • Users
                            • Groups