为什么我的通用列表中的每个元素都相同? (VB)

时间:2014-08-29 23:18:24

标签: 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显示相同的标题。

相册的定义如下:

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种不同的元素?

2 个答案:

答案 0 :(得分:2)

Album是引用类型 - 所有类都是引用类型。值和引用类型的赋值语义是不同的。值类型(如double,integer等)由包含其值的变量表示。

引用类型仅包含对其类型对象的引用(或指针)。当你写:

 Dim album As New Album

您正在分配变量album并指向新创建的Album类实例。 (顺便说一句,由于VB不区分大小写,所以使用相同名称和不同大小写的变量是个坏主意!您应该考虑调用类似_albumanAlbum的变量或其他任何变量不同的拼写)。

无论如何,当你继续做下去的时候:

For i = 1 To 10
  album.AlbumId = i
  album.Title = "Album " & i
  albums.Add(album)
Next

您正在更改已创建的单个Album实例的属性,并且正在重复将相同的相册添加到列表中。该列表最终会对同一个相册对象进行十次引用,因为您尚未创建多个相册对象。

您需要做的是每次都创建一个新实例:

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

每次你写:

anAlbum = New Album

您正在创建一个新的Album对象,并且正在覆盖变量anAlbum中的引用以指向新创建的对象。然后,将其添加到列表中,将新引用添加到新对象。


现在,对于具有合理大小的值类型的简单数据结构,使用Class的替代方法是使用StructureStructure是值类型,因此在分配时会被复制(与Classes或其他引用类型不同)。如果您想要值类型赋值语义,并且不关心多态或继承等“经典”事物,那么您可以将Album类重新定义为结构,如下所示:

 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

ClassStructure之间进行选择是设计过程中的一个重要部分,但是在这里完全处理的主题却相当深入。请注意,包含引用类型的Structure可能会很棘手,因为在赋值时,其值成员将复制,但其引用成员将继续指向相同的对象!


如需进一步阅读,可以从文档开始:

MSDN - Value Types and Reference Types

答案 1 :(得分:0)

我建议您对代码进行以下更改:

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