我有一个Collection Class(或者更确切地说是一个字典类),用于存储可变数量的edge对象。当我尝试通过循环填充包含所有信息的Dictionary时,数据会被不断覆盖,我似乎无法弄清楚原因。相关课程的代码如下:
null
生成Edges对象的Sub如下:
Option Explicit
Private pEdges As New Scripting.Dictionary
Property Get Count() As Long
Count = pEdges.Count
End Property
Property Get EdgeByName(ByVal iName As Variant) As cEdge
Set EdgeByName = pEdges(iName)
End Property
'Would it be better to pass all of the data to this add sub, and create
'the class objects here, rather than creating a temporary class object and
'just passing it along?
Sub Add(ByVal iEdge As cEdge)
Dim Edge As New cEdge
Set Edge = iEdge
pEdges.Add Edge.Name, Edge
End Sub
Sub Remove(ByVal iName As Variant)
pEdges.Remove (iName)
End Sub
Sub RemoveAll()
pEdges.RemoveAll
End Sub
Sub PrintNames()
Dim Key As Variant
For Each Key In pEdges
Debug.Print Key & " - " & pEdges(Key).Name & vbCrLf;
Next
Debug.Print vbdrlf;
End Sub
dEdges.PrintNames子句的输出是我用来调试它的(因为Watches窗口没有显示字典的项目数据)。 当循环继续时,它会打印键对应的边缘对象的Key和Name Value。如果工作正常,这两个字符串应该是相同的。虽然如此,每次我向字典添加一个新的边缘对象时,它都会覆盖所有先前输入的键的对象。我怀疑这与我创建一个TempEdge变量传递给Collection Class的事实有关,但我不确定。
输出示例:
Sub CalculateEdges(cCavities() As cCavity, dEdges As cEdges)
Dim i As Integer
For i = 1 To UBound(cCavities)
Dim TempEdge As cEdge
Set TempEdge = New cEdge
Dim AdjSize As Integer
AdjSize = cCavities(i).AdjacencySize
If AdjSize> MaxEdges Then MaxEdges = AdjSize
Dim j As Integer
For j = 1 To AdjSize
With TempEdge
'Edge Names are a combination of two node names
.Name = cCavities(i).Name & cCavities(i).Adjacency(j)
'Sets the start node (Object) for the edge
.SetNode cCavities(i), 0
'Sets the end node (Object) for the edge
.SetNode BackGround.NodeByName(cCavities, cCavities(i).Adjacency(j)), 1
'Used later in program
.Value = 0
End With
dEdges.Add TempEdge
dEdges.PrintNames
Next j
Next i
End Sub
这只是一个被测试的单个数据点,但让我向您保证,cEdge对象中的所有变量都会被覆盖,而不仅仅是名称字符串。这是最容易检查的,因为它只是一个字符串。
作为旁注,如果有办法看到存储在字典中的对象,类似于"手表"窗口,我非常想知道怎么做。我在这一点上甚至使用临时边缘的全部原因是我可以跟踪循环中任何给定点进入字典的数据。
第二方注意,如果我可以使这个工作,我很可能将cCavities数组切换到类似的集合类。它目前不是一个,因为我似乎无法使它们正常工作。
答案 0 :(得分:1)
将集合“ TempEdge = New cEdge”移入循环将在每个循环中创建一个新实例和一个新指针位置,同时保持对先前指针的集合引用。
/**
* @param {import("./mymodule").customProps } customProps
*/
export function setGlobalStyle(obj, customProps) {
customProps. // has full auto-completion
结束子
答案 1 :(得分:0)
我继续将所有数据传递给add例程的想法,似乎已经解决了这个问题。我仍然想知道为什么我使用的方法不起作用,所以请随时评论或回答。
解决方案是更改cEdges.Add Sub以接受曾经传递给临时边缘变量的所有单个参数:
Sub Add(ByVal iName As String, iNode1 As cCavity, iNode2 As cCavity, iValue As Integer)
Dim Edge As New cEdge
With Edge
.Name = iName
.SetNode iNode1, 0
.SetNode iNode2, 1
.Value = iValue
End With
pEdges.Add Edge.Name, Edge
End Sub
这会将填充循环更改为:
Sub CalculateEdges(cCavities() As cCavity, dEdges As cEdges)
Dim i As Integer
For i = 1 To UBound(cCavities)
Dim AdjSize As Integer
AdjSize = cCavities(i).AdjacencySize
If AdjSize > MaxEdges Then MaxEdges = AdjSize
Dim j As Integer
For j = 1 To AdjSize
dEdges.Add cCavities(i).Name & cCavities(i).Adjacency(j), cCavities(i), BackGround.NodeByName(cCavities, cCavities(i).Adjacency(j)), 0
dEdges.PrintNames
Next j
Next i
End Sub
此代码,尤其是.Add行,可以清除。我很可能会这样做,但现在这很好。
编辑:经过进一步的研究和更多的反复试验,我发现了数据被覆盖的原因。 Set
关键字只创建一个指向原始值的指针,有效地使我的上面的代码有一个对象,TempEdge变量,以及指向它的一大堆不同的头。这就是为什么当编辑Temp边缘时,所有后续头部都会改变。