翻译 "收益率回报" 到VB


大家好,我还有另一个翻译问题,甚至 – chat.openai.com – 都无法帮助我,我使用 vb 2010,并且我很清楚从 2012 版本开始支持“yield”,但为了兼容性我必须使用2010年版本。 有没有一个不太牵强的替代方案来解决这个问题? 代码如下:

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;
         }

我希望得到您的帮助并谢谢您。

我尝试过的:

我尝试了这个,但它不起作用,程序崩溃了,我重新启动了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

解决方案2

我不会说这“不是一项简单的工作”,只是与 C# 的做法不同而已。 具体方法如下: 迭代器- Visual Basic | 微软学习[^]

因此,据猜测(未测试),VB.Net 版本应该是:

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

解决方案3

曾经有一段时间, yield 可用于 C# 但不在 vb。 如果 2010 年是这种情况,那么检查是否 IEnumerable 接口可用于 vb 在2010年?

如果 IEnumerable 接口可用于 vb 在 2010 年,您可以为您创建的类实现该接口,以便创建 Yield 就像功能一样。 看 本文[^],其实没那么难。

如果 IEnumerable 接口不可用 vb 在 2010 年,然后要么查看 OriginalGriff 的答案,要么实现下面的代码,但删除所有接口实现。 不实现接口意味着您将无法使用 For ... Each 但是 While .MoveNext() = True 代码应该仍然可以工作 – 下面包含示例。

例如(我还没有测试过这段代码,所以会有一些拼写错误应该很容易修复)。
首先,您创建一个可以枚举的新类(实现 IEnumerable)。 我上面链接的文章详细描述了所有这些,但实质上新类实现了 IEnumerable 这意味着它必须有能力创建并返回一个实现了 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

然后我们创建可枚举对象将使用的枚举器。 您可以看到整数数组逐渐从代码传递到 IEnumerable 对象,然后 IEnumerator 目的。 您需要根据您的需要决定是浅拷贝(通过引用)还是深拷贝(通过值)。

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

然后修改原始代码以使用这个新类。 注意,有两种方法可以进行枚举

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

然后你需要实施 IEnumerator 接口为 ThingEnumerator 班级。

网络
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

解决方案1

コメント

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