0

在 vb.net 中,我正在尝试创建复制/反向/合并堆栈的扩展。请注意,它可能已经存在,但我面临一个问题。

我有一个名为 utility.vb 的模块,它包含一大堆<Extension()>,就像我正在尝试编写的 Duplicate 一样。

''' <summary>
''' Duplicate a stack of object to another
''' </summary>
''' <typeparam name="T">Object type in the stack</typeparam>
''' <param name="s">Stack to duplicate</param>
''' <returns></returns>
<Extension()>
Public Function Duplicate(Of T)(ByVal s As Stack(Of T())) As Stack(Of T())
    Dim tmp As New Stack(Of T())
    For i As Integer = s.Count - 1 To 0 Step -1
        tmp.Push(s(i))
    Next
    Return tmp
End Function

我正在一个名为 labelStack 的堆栈中进行各种推送。但是当我从我的代码中调用 Duplicate 函数时(因为我需要多次重复使用同一个堆栈),它没有编译(请注意堆栈是由自己创建的对象类组成的)

Dim summaryStack As Stack(Of CCNode) = labelStack.Duplicate()

错误是“'Duplicate' 不是 'Stack(Of MyForm.CCNode)' 的成员”

我还尝试像这样更改扩展名的签名:

Public Function Duplicate(Of T As {New})(ByVal s As Stack(Of T())) As Stack(Of T())

但没有任何成功。

有人可以帮助我(指出我的错误,纠正它或给我一种方法来实现我的需要,而无需自己编写函数)?

PS:我使用 Stack 是因为我需要以 Push 的相反顺序弹出,这似乎很合适。

4

1 回答 1

1

你做错了。如果您想重用或反转或任何此类事情,那么您不应该从创建一个Stack(Of T)开始。List(Of T)根据您是否希望能够调整内容,创建一个数组或一个,然后您可以从中创建任意数量Stack(Of T)Queue(Of T)对象。这两个类都有一个接受 aIEnumerable(Of T)作为参数的构造函数,因此您可以将数组或任意数量的构造函数传递给List(Of T)您,例如

Dim items = {1, 2, 3, 4}
Dim s1 As New Stack(Of Integer)(items)
Dim s2 As New Stack(Of Integer)(items.Reverse())
Dim q1 As New Queue(Of Integer)(items)
Dim q2 As New Queue(Of Integer)(items.Reverse())

也就是说,我只是这样做了:

Imports System.Runtime.CompilerServices

Public Module StackExtensions

    <Extension>
    Public Function Copy(Of T)(source As Stack(Of T)) As Stack(Of T)
        Dim newStack As New Stack(Of T)

        For Each item In source.Reverse()
            newStack.Push(item)
        Next

        Return newStack
    End Function

End Module

它完全按照您的意愿工作。我希望输入堆栈在那之后是空的,因为我认为枚举 aStack(Of T)会弹出每个项目,但显然它不会。

实际上,我刚刚意识到这意味着Stack(Of T)构造函数将接受另一个Stack(Of T)作为参数,这使得扩展方法更加简单:

Imports System.Runtime.CompilerServices

Public Module StackExtensions

    <Extension>
    Public Function Copy(Of T)(source As Stack(Of T)) As Stack(Of T)
        Return New Stack(Of T)(source.Reverse())
    End Function

End Module

这太简单了,我认为扩展方法甚至不值得费心。

尽管如此,我仍然会使用数组或List(Of T)作为单一事实来源并从中创建所有堆栈。这样一来,您就不可能在创建所需的所有副本之前弹出一个项目。

于 2020-05-12T09:38:03.523 回答