Vb.net 为什么我的通用列表中的每个元素都是相同的?(VB)
使用以下代码:Vb.net 为什么我的通用列表中的每个元素都是相同的?(VB),vb.net,visual-studio-2013,Vb.net,Visual Studio 2013,使用以下代码: Dim albums As New List(Of Album) Dim album As New Album Dim s1 As String For i = 1 To 10 album.AlbumId = i album.Title = "Album " & i albums.Add(album) Next For Each a In albums s1 = a.Title Next 在“For Each”循环中的每次迭代中检查s1都会显示相同的
Dim albums As New List(Of Album)
Dim album As New Album
Dim s1 As String
For i = 1 To 10
album.AlbumId = i
album.Title = "Album " & i
albums.Add(album)
Next
For Each a In albums
s1 = a.Title
Next
在“For Each”循环中的每次迭代中检查s1都会显示相同的标题
相册的定义如下:
Public Class Album
Private mAlbumId As Integer
Public Property AlbumId() As Integer
Get
Return mAlbumId
End Get
Set(ByVal value As Integer)
mAlbumId = value
End Set
End Property
Private mTitle As String
Public Property Title() As String
Get
Return mTitle
End Get
Set(ByVal value As String)
mTitle = value
End Set
End Property
End Class
我缺少什么,以便可以存储和检索10个不同的元素?
Album
是一个引用类型-所有类都是引用类型。值和引用类型的赋值语义不同。值类型(如double、integer等)由包含其值的变量表示
引用类型仅包含指向其类型的对象的引用(或指针)。当你写作时:
Dim album As New Album
anAlbum = New Album
您正在分配一个变量album
,并指向新创建的album
类实例。(顺便说一下,由于VB不是区分大小写的,所以有同名的变量和不同的情况是不好的!您应该考虑调用变量,比如<代码>专辑[或<代码> ANSUBS/<代码>或任何不同拼写的任何东西。
在任何情况下,当您继续执行以下操作时:
For i = 1 To 10
album.AlbumId = i
album.Title = "Album " & i
albums.Add(album)
Next
您正在更改已创建的单个相册
实例的属性,并重复将同一个相册添加到列表中。该列表以对同一相册对象的十个引用结束,因为您没有创建多个引用
您需要做的是每次创建一个新实例:
dim anAlbum as Album 'do not create one yet!
For i = 1 To 10
anAlbum = New Album 'instead, make a new one each time
anAlbum.AlbumId = i
anAlbum.Title = "Album " & i
Albums.Add(anAlbum)
Next
每次你写:
Dim album As New Album
anAlbum = New Album
您正在创建一个新的Album
对象,并覆盖变量anAlbum
中的引用以指向新创建的对象。将其添加到列表中,然后将新引用添加到新对象
现在,对于大小合理的值类型的简单数据结构,使用
类
的替代方法是使用结构
<代码>结构s是值类型,因此在赋值时会被复制(与类
或其他引用类型不同)。如果您想要值类型分配语义,并且不关心多态性或继承之类的“经典”事情,那么您可以将相册
类重新定义为结构,如下所示:
Public Structure Album
Private mAlbumId As Integer
Public Property AlbumId() As Integer
Get
Return mAlbumId
End Get
Set(ByVal value As Integer)
mAlbumId = value
End Set
End Property
Private mTitle As String
Public Property Title() As String
Get
Return mTitle
End Get
Set(ByVal value As String)
mTitle = value
End Set
End Property
End Structure
然后这类事情就会如你所期望的那样起作用:
Dim AnAlbum As New Album
For i = 1 To 10
AnAlbum.AlbumId = i
AnAlbum.Title = "Album " & i
albums.Add(AnAlbum)
Next
在类
和结构
之间进行选择是设计过程中的一个重要部分,但这是一个太深的主题,在这里无法完全讨论。请注意,包含引用类型的结构可能很棘手,因为在赋值下,其值成员将复制,但其引用成员将继续指向相同的对象
为了进一步阅读,可以从以下文档开始:
我建议您对代码进行以下更改:
Dim albums As New List(Of Album)
Dim s1 As String = ""
For i = 1 To 10
Dim Albm As New Album 'Define the album here instead to be sure that nothing goes wrong
Albm.AlbumId = i
Albm.Title = "Album " & i
albums.Add(Albm)
Next
For Each a In albums
s1 = s1 & a.Title & Environment.NewLine 'This will list all the albums in one string
'Just doing s1 = a.Title will result in the string changing ONLY to the latest album's Title.
'Doing this will list all albums in one string
Next
上面的“For Each a…”循环将给出以下结果:
专辑1
专辑2
专辑3
专辑4
专辑5
专辑6
专辑7
专辑8
专辑9
专辑10
您只创建了一个相册对象。您不能期望最终得到10个不同的对象。查看您最喜欢的VB.NET语言书,了解引用类型和值类型之间的差异。1:如何检查s1字符串?你只是向我们展示了你是如何设置的。2:像s1循环那样没有延迟的for循环几乎可以立即完成。3.由于您仅将s1文本设置为当前相册的标题,因此它将始终显示最新的相册。查看我的答案了解更多信息…在回答Vincent时,我只是在Next上设置了一个断点,并在循环时检查了该值。如果我能输出结果,你下面的代码会很好,但也可以在代码后面看到我的评论。请确保,但在上面的For循环中,当调用Add时,它不应该是针对相册而不是Albm吗?正如你在上面发布的那样,工作得很好。非常愚蠢的错误,我真的需要外观。谢谢!我认为使用类比使用结构要好得多,但一定要记住这一点。