We help IT Professionals succeed at work.

Convert yield statement from C# to VB

bobinorlando
bobinorlando used Ask the Experts™
on
I'm trying to run the code from this page after converting to VB but I'm not sure what to do with the yield statements in C# .

http://blog.abodit.com/2010/03/a-simple-web-crawler-in-c-using-htmlagilitypack/

Getting error at this line:

 // Success, hand off the page

                    yield return new WebPage.Internal() { Url = url, HtmlDocument = doc };

and farther down the page


if (urlRoot.IsBaseOf(urlNext))
                            {
                                queue.Enqueue(urlNext);
                            }
                            else
                            {
                                yield return new WebPage.External() { Url = urlNext };
                            }

Thanks in advance.

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Shahan AyyubSenior Software Engineer

Commented:
Here is the complete conversion using this link:
http://www.developerfusion.com/tools/convert/csharp-to-vb/



Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports HtmlAgilityPack
Imports System.Net

Namespace LinkChecker.WebSpider
	''' <summary>
	''' A result encapsulating the Url and the HtmlDocument
	''' </summary>
	Public MustInherit Class WebPage
		Public Property Url() As Uri
			Get
				Return m_Url
			End Get
			Set
				m_Url = Value
			End Set
		End Property
		Private m_Url As Uri

		''' <summary>
		''' Get every WebPage.Internal on a web site (or part of a web site) visiting all internal links just once
		''' plus every external page (or other Url) linked to the web site as a WebPage.External
		''' </summary>
		''' <remarks>
		''' Use .OfType WebPage.Internal to get just the internal ones if that's what you want
		''' </remarks>
		Public Shared Function GetAllPagesUnder(urlRoot As Uri) As IEnumerable(Of WebPage)
			Dim queue = New Queue(Of Uri)()
			Dim allSiteUrls = New HashSet(Of Uri)()

			queue.Enqueue(urlRoot)
			allSiteUrls.Add(urlRoot)

			While queue.Count > 0
				Dim url As Uri = queue.Dequeue()

				Dim oReq As HttpWebRequest = DirectCast(WebRequest.Create(url), HttpWebRequest)
				oReq.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5"

				Dim resp As HttpWebResponse = DirectCast(oReq.GetResponse(), HttpWebResponse)

				Dim result As WebPage

				If resp.ContentType.StartsWith("text/html", StringComparison.InvariantCultureIgnoreCase) Then
					Dim doc As New HtmlDocument()
					Try
						Dim resultStream = resp.GetResponseStream()
						doc.Load(resultStream)
						' The HtmlAgilityPack
						result = New Internal() With { _
							.Url = url, _
							.HtmlDocument = doc _
						}
					Catch ex As System.Net.WebException
						result = New WebPage.Error() With { _
							.Url = url, _
							.Exception = ex _
						}
					Catch ex As Exception
						ex.Data.Add("Url", url)
						' Annotate the exception with the Url
						Throw
					End Try

					' Success, hand off the page
					yield Return New WebPage.Internal() With { _
						.Url = url, _
						.HtmlDocument = doc _
					}

					' And and now queue up all the links on this page
					For Each link As HtmlNode In doc.DocumentNode.SelectNodes("//a[@href]")
						Dim att As HtmlAttribute = link.Attributes("href")
						If att Is Nothing Then
							Continue For
						End If
						Dim href As String = att.Value
						If href.StartsWith("javascript", StringComparison.InvariantCultureIgnoreCase) Then
							Continue For
						End If
						' ignore javascript on buttons using a tags
						Dim urlNext As New Uri(href, UriKind.RelativeOrAbsolute)

						' Make it absolute if it's relative
						If Not urlNext.IsAbsoluteUri Then
							urlNext = New Uri(urlRoot, urlNext)
						End If

						If Not allSiteUrls.Contains(urlNext) Then
							allSiteUrls.Add(urlNext)
							' keep track of every page we've handed off
							If urlRoot.IsBaseOf(urlNext) Then
								queue.Enqueue(urlNext)
							Else
								yield Return New WebPage.External() With { _
									.Url = urlNext _
								}
							End If
						End If
					Next
				End If
			End While
		End Function

		'''// <summary>
		'''// In the future might provide all the images too??
		'''// </summary>
		'public class Image : WebPage
		'{
		'}

		''' <summary>
		''' Error loading page
		''' </summary>
		Public Class [Error]
			Inherits WebPage
			Public Property HttpResult() As Integer
				Get
					Return m_HttpResult
				End Get
				Set
					m_HttpResult = Value
				End Set
			End Property
			Private m_HttpResult As Integer
			Public Property Exception() As Exception
				Get
					Return m_Exception
				End Get
				Set
					m_Exception = Value
				End Set
			End Property
			Private m_Exception As Exception
		End Class

		''' <summary>
		''' External page - not followed
		''' </summary>
		''' <remarks>
		''' No body - go load it yourself
		''' </remarks>
		Public Class External
			Inherits WebPage
		End Class

		''' <summary>
		''' Internal page
		''' </summary>
		Public Class Internal
			Inherits WebPage
			''' <summary>
			''' For internal pages we load the document for you
			''' </summary>
			Public Overridable Property HtmlDocument() As HtmlDocument
				Get
					Return m_HtmlDocument
				End Get
				Friend Set
					m_HtmlDocument = Value
				End Set
			End Property
			Private Overridable m_HtmlDocument As HtmlDocument
		End Class
	End Class
End Namespace

Open in new window

Commented:
Take a look at this, i found it very usefull:

http://www.ytechie.com/2009/02/using-c-yield-for-readability-and-performance.html

So you could just create a list in VB and return that after the iteration in stead of using yield.

Some pages say VB.NET does have the yield functionality (in that case you could translate it 1-to-1), others say it doesn't. Haven't tested out myself, but if the compiler starts complaining when using yield you can use the workaround.

Author

Commented:
Yup. But that's the same link I used and you will see the yield statements that do not compute in vb.
Fernando SotoRetired
Distinguished Expert 2017
Commented:
Hi bobinorlando;

The VB .Net language does not support iterators and therefore does not have a keyword yield to support that functionality.

Fernando