Solved

Convert YIELD in C# to vb.net

Posted on 2011-02-23
5
975 Views
Last Modified: 2012-05-11
How can I quickly convert this to VB please

            foreach (string dir in subDirs.Reverse())
                {
                    DirectoryInfo directory = new DirectoryInfo(dir);
                    yield return new File(directory.Name, parentDirectory);
                    dirs.Push(dir);
                }
0
Comment
Question by:HankinCooper
  • 3
  • 2
5 Comments
 
LVL 23

Expert Comment

by:wdosanjos
ID: 34963099
Unfortunately, VB does not have a 'yield return' equivalent.  There are some workarounds though.  Please check the following Visual Studio Magazine article for more details:

http://visualstudiomagazine.com/Articles/2009/02/01/Use-Iterators-in-VB-Now.aspx?Page=2
0
 

Author Comment

by:HankinCooper
ID: 34963368
ok, so created this class, where/how to I apply it to my example please? thanks...



Imports System.IO

Namespace ains
    Public Class VByield
        Implements IEnumerable(Of String)
        Implements IEnumerator(Of String)

        Private _rdr As TextReader
        Private _current As String

        Sub New(ByVal rdr As TextReader)
            _rdr = rdr
        End Sub


        ''' <summary>
        '''    Get's an enumerator to read lines from a stream
        ''' </summary>
        ''' <returns>IEnumerator(Of String)</returns>
        ''' <remarks>Can only be called once due to the underlying stream. Not thread safe.</remarks>
        ''' <exception cref="InvalidOperationException">thrown if GetEnumerator is called more than once</exception>
        '''
        Public Function GetEnumerator() As IEnumerator(Of String) Implements IEnumerable(Of String).GetEnumerator
            Static iFirstTime As Int32
            If iFirstTime = 0 AndAlso Threading.Interlocked.Increment(iFirstTime) = 1 Then
                Return Me
            Else
                Throw New InvalidOperationException("GetEnumerator can only be called once on a stream")
            End If
        End Function


        Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
            _current = _rdr.ReadLine()
            Return _current IsNot Nothing
        End Function


        Private Function IEnumerator_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
            Return GetEnumerator()
        End Function


        Public ReadOnly Property Current() As String Implements IEnumerator(Of String).Current
            Get
                Return _current
            End Get
        End Property

        Private ReadOnly Property IEnumerator_Current() As Object Implements IEnumerator.Current
            Get
                Return Current
            End Get
        End Property


        Private Sub Reset() Implements IEnumerator.Reset
            Throw New NotImplementedException()
        End Sub

        Public Sub Dispose() Implements IDisposable.Dispose
            'not implemented
        End Sub

    End Class
End Namespace
0
 

Author Comment

by:HankinCooper
ID: 34963374
sorry, and this function..

        Function Lines(ByVal rdr As TextReader) As IEnumerable(Of String)
            Return New VByield(rdr)
        End Function
0
 
LVL 23

Accepted Solution

by:
wdosanjos earned 500 total points
ID: 34965129
The example code you provided is not complete, so I cannot provide a matching sample.  The code below implements the basic pattern by providing an iterator that returns MyFile objects from the directory provided. I think you should be able to adapt it to your specific application.

Option Strict On
Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.IO
Imports System.Linq
Imports System.Runtime.CompilerServices


Module Module1

    Sub Main()
        Dim root As DirectoryInfo

        root = New DirectoryInfo("C:\Windows\Temp")

        Dim query = From file In root.Files _
                    Where file.Name.EndsWith(".dat", StringComparison.CurrentCultureIgnoreCase)

        For Each file In query
            Console.WriteLine("{0}{1}", file.ParentDirectory.FullName, file.Name)
        Next

        Console.ReadLine()

    End Sub

End Module


Public Class MyFile
    Private _name As String
    Public Property Name() As String
        Get
            Return _name
        End Get
        Set(ByVal value As String)
            _name = value
        End Set
    End Property

    Private _parentDir As DirectoryInfo
    Public Property ParentDirectory() As DirectoryInfo
        Get
            Return _parentDir
        End Get
        Set(ByVal value As DirectoryInfo)
            _parentDir = value
        End Set
    End Property

    Sub New(ByVal name As String, ByVal parentDir As DirectoryInfo)
        _name = name
        _parentDir = parentDir
    End Sub
End Class


Module DirectoryInfoExtensions

    <Extension()> _
    Function Files(ByVal dir As DirectoryInfo) As IEnumerable(Of MyFile)
        Return New DirectoryFileEnumerator(dir)
    End Function

    Public Class DirectoryFileEnumerator
        Implements IEnumerable(Of MyFile)
        Implements IEnumerator(Of MyFile)

        Private _dir As DirectoryInfo
        Private _current As MyFile
        Private _files() As FileInfo
        Private _index As Integer

        Sub New(ByVal dir As DirectoryInfo)
            _dir = dir
            _files = _dir.GetFiles()
            _index = 0
        End Sub


        Public Function GetEnumerator() As IEnumerator(Of MyFile) Implements IEnumerable(Of MyFile).GetEnumerator
            Static iFirstTime As Int32
            If iFirstTime = 0 AndAlso Threading.Interlocked.Increment(iFirstTime) = 1 Then
                Return Me
            Else
                Throw New InvalidOperationException("GetEnumerator can only be called once on a stream")
            End If
        End Function


        Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
            Dim hasNext As Boolean = False

            If _index < _files.Length Then
                _current = New MyFile(_files(_index).Name, _dir)
                _index = _index + 1
                hasNext = True
            End If

            Return hasNext
        End Function


        Private Function IEnumerator_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
            Return GetEnumerator()
        End Function


        Public ReadOnly Property Current() As MyFile Implements IEnumerator(Of MyFile).Current
            Get
                Return _current
            End Get
        End Property

        Private ReadOnly Property IEnumerator_Current() As Object Implements IEnumerator.Current
            Get
                Return Current
            End Get
        End Property


        Private Sub Reset() Implements IEnumerator.Reset
            Throw New NotImplementedException()
        End Sub

        Public Sub Dispose() Implements IDisposable.Dispose
            'not implemented
        End Sub

    End Class



End Module

Open in new window

0
 

Author Comment

by:HankinCooper
ID: 34966043
you are awesome!!!!!!!!!!!!!
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
ASP.NET Web API or ASP.NET Core MVC? 3 52
C# Offline Apllication 5 55
Angular JS Route 3 52
User Authentication using Digital Certificate 2 24
In order to hide the "ugly" records selectors (triangles) in the rowheaders, here are some suggestions. Microsoft doesn't have a direct method/property to do it. You can only hide the rowheader column. First solution, the easy way The first sol…
Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, just open a new email message. In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…

920 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now