Traduction en cours "rendement" en VB

la programmation


Bonjour à tous, j’ai un autre problème de traduction qui même – chat.openai.com – ne pourrait pas m’aider, j’utilise vb 2010, et je sais très bien qu’à partir de la version 2012 “yield” est supporté, mais pour des raisons de compatibilité je dois utiliser la version 2010. Existe-t-il une alternative pas trop farfelue pour contourner le problème ? Le code est comme suit:

C#
public IEnumerable<Range> GetRanges(string regexPattern)
         {
             var range = new Range(this);
             range.SelectAll();
             //
             foreach (Range r in range.GetRanges(regexPattern, RegexOptions.None))
                 yield return r;
         }

J’espère votre aide et merci.

Ce que j’ai essayé :

J’ai essayé ça, mais ça ne marche pas, le programme plante et je redémarre vb…

VB
Module Module1
     Sub Main()
         For Each number In GenerateNumbers(1, 5)
             Console.WriteLine(number)
         Next
         Console.ReadLine()
     End Sub

     Function GenerateNumbers(start As Integer, count As Integer) As Integer()
         Dim result(count - 1) As Integer
         For i As Integer = 0 To count - 1
             result(i) = start + i
         Next
         Return result
     End Function
End Module

Solution 2

Je ne dirais pas que ce n’était « pas un travail simple », mais simplement fait différemment du C#. Voici comment: Itérateur – Visual Basic | Microsoft Apprendre[^]

Ainsi, à première vue (non testé), la version VB.Net devrait être :

VB
Public Iterator Function GetRanges(regexPattern As String) As IEnumerable(Of Range)
    Dim range As New Range(Me)
    range.SelectAll()
    
    For Each r As Range In range.GetRanges(regexPattern, RegexOptions.None)
        Yield r
    Next
End Function

Solution 1

Solution 3

Il fut un temps où yield était disponible dans C# mais pas dans vb. Si tel était le cas en 2010, vérifiez si le IEnumerable l’interface était disponible dans vb en 2010?

Si la IEnumerable l’interface était disponible dans vb en 2010, vous pouvez alors implémenter cette interface pour une classe que vous créez afin de créer un Yield comme la fonctionnalité. Voir Cet article[^]ce n’est pas si difficile en fait.

Si la IEnumerable l’interface n’était pas disponible dans vb en 2010, consultez la réponse d’OriginalGriff ou implémentez le code ci-dessous mais supprimez toutes les implémentations d’interface. Ne pas implémenter les interfaces signifie que vous ne pourrez pas utiliser For ... Each mais le While .MoveNext() = True le code devrait toujours fonctionner – des exemples sont inclus ci-dessous.

Par exemple (je n’ai pas testé ce code donc il y aura des fautes de frappe qui devraient être faciles à corriger).
Vous créez d’abord une nouvelle classe qui peut être énumérée (implémente IEnumerable). L’article que j’ai lié ci-dessus décrit tout cela en détail, mais la nouvelle classe implémente essentiellement IEnumerable ce qui signifie qu’il doit avoir la capacité de créer et de renvoyer un objet qui implémente IEnumerator.

VB
Public Class VBYield
    Implements IEnumerable(Of Integer)
    
    Private _enumerableobject As Integer()
    Private _thingenumerator As ThingEnumerator
    
    Public Sub New(EnumerableObject As Integer())
        Me._enumerableobject = EnumerableObject
    End Sub
    
    Public Function GetEnumerator() As IEnumerator(Of Double) Implements IEnumerable(Of Integer).GetEnumerator
        Return New ThingEnumerator(Me._enumerableobject)
    End Function
    
    ''' <summary>
    ''' [Use GetEnumerator instead]
    ''' </summary>
    Public Function GetEnumerator1() As IEnumerator Implements Collections.IEnumerable.GetEnumerator
        Return Me.GetEnumerator()
    End Function

Ensuite, nous créons l’énumérateur qui sera utilisé par l’objet énumérable. Vous pouvez voir que le tableau d’entiers est progressivement transmis de votre code au IEnumerable objet, puis le IEnumerator objet. Vous devez décider s’il doit s’agir de copies superficielles (par référence) ou profondes (par valeur) en fonction de vos besoins.

VB
Public Class ThingEnumerator
    Implements IEnumerator(Of Integer)
 
    Private _enumerableobject As Integer()
    Private _index As Integer
    Private _curItem As Integer
    Private _lastItem As Integer
 
    Public Sub New(enumerableobject As Integer())
        Me._enumerableobject = enumerableobject
        Me._index = -1
        Me._curItem = Nothing
        Me._lastItem = enumerableobject.GetUpperBound(0)
    End Sub

Modifiez ensuite votre code d’origine pour utiliser cette nouvelle classe. Notez qu’il existe deux manières de faire l’énumération

VB
Sub Main()
    'Create the object that can be enumerated
    Dim enumerablething As VBYield = New VBYield(GenerateNumbers(1,5))
    
    'There are two ways to enumerate the contents of our new object
    'This first way makes use of the fact that the object is enumerable (cannot use For Each if it isn't)
    For Each number As Interger in VBYield
        Console.WriteLine(number.ToString())
    Next
    
    'This second way ignorers the fact that the object is enumerable and accesses the methods of the enumerator object directlty
    'Use the enumerable object to get an enumerator object and then use MoveNext() and Current() to traverse its contents
    Dim enumeratorofthing As IEnumerator = VBYield.GetEnumerator()
    While enumeratorofthing.MoveNext() = True
        Console.WriteLine(enumeratorofthing.Current.ToString())
    End While

End Sub

Function GenerateNumbers(start As Integer, count As Integer) As Integer()
    Dim result(count - 1) As Integer
    For i As Integer = 0 To count - 1
        result(i) = start + i
    Next
    Return result
End Function

Ensuite, vous devez mettre en œuvre le IEnumerator interface pour le ThingEnumerator classe.

VB.NET
Public ReadOnly Property Current As Double Implements IEnumerator(Of Integer).Current
    Get
        If IsNothing(Me._curItem) Then
            Throw New InvalidOperationException()
        End If
        Return Me._curItem
    End Get
End Property

Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
    If Me._index = Me._lastItem Then
        Return False
    End If
    Me._index += 1
    Me._curItem = Me._enumerableobject(Me._index)
    Return True
End Function

Public Sub Reset() Implements IEnumerator.Reset
    Me._index = -1
    Me._curItem = Nothing
End Sub

コメント

タイトルとURLをコピーしました