【问题标题】:Is there a smart way to duplicate a Stack(Of ...)有没有一种聪明的方法来复制 Stack(Of ...)
【发布时间】:2020-08-28 01:24:37
【问题描述】:

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

我有一个名为 utility.vb 的模块,其中包含一大堆 ,例如我正在尝试编写的 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())

但没有任何成功。

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

P.S.:我使用 Stack 是因为我需要以 Push 的相反顺序 Pop 并且看起来很合适。

【问题讨论】:

  • 根据您的方法声明,您需要传入一堆 T 数组,然后返回一堆 T 数组。我怀疑那是您想要的。假设我了解您的要求,请参阅我的答案以获得正确的声明。

标签: vb.net stack compiler-services


【解决方案1】:

你做错了。如果您想重用或反转或任何类似的事情,那么您不应该从创建Stack(Of T) 开始。创建一个数组或List(Of T),这取决于您是否希望能够调整内容,然后您可以从中创建任意数量的Stack(Of T)Queue(Of T) 对象。这两个类都有一个构造函数,它接受 IEnumerable(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

它完全按照您的意愿工作。我希望输入堆栈在那之后是空的,因为我认为枚举 Stack(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) 作为单一事实来源,并从中创建所有堆栈。这样一来,您就不可能在创建所需的所有副本之前弹出一个项目。

【讨论】:

  • 我习惯了 List(Of ...) 但我不确定它会保持我添加元素的顺序。我也会看看 Queue(Of ...) 但是当我需要 LIFO 时它是 FIFO。无论如何,学习一个新容器总是很有趣的。
  • 鉴于您可以通过索引访问List(Of T) 中的项目,您可以确保顺序保持一致。我刚才提到Queue 是因为它的工作原理类似,而不是因为在这种情况下你必须使用它。
猜你喜欢
  • 2015-04-07
  • 2021-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-19
  • 2022-01-23
  • 1970-01-01
相关资源
最近更新 更多