Vb.net net的可克隆实现

Vb.net net的可克隆实现,vb.net,implementation,icloneable,Vb.net,Implementation,Icloneable,我知道在这件事上有很多问题。但就我个人而言,我无法理解这些答案,也无法在我的例子中使用它们。我是vb.net新手,我不能真正将一般示例实现到我的特定示例中。我基本上是这样的: dim a as New list(of player) EDIT: dim b as New list(of player) 'previously was: dim b as new player Class player Public name As String '[more] End Cl

我知道在这件事上有很多问题。但就我个人而言,我无法理解这些答案,也无法在我的例子中使用它们。我是vb.net新手,我不能真正将一般示例实现到我的特定示例中。我基本上是这样的:

dim a as New list(of player)
EDIT: dim b as New list(of player)    'previously was: dim b as new player

Class player
    Public name As String
    '[more]
End Class
[……]

a.Add(New player)
b.Add(New player)
a(0).name="john"
b=a
a(0).name="jack"
msgbox(b(0).name) 'it will print jack instead of john
我现在可以用iClonable来实现这一点,但在阅读了很多关于它的内容后,我无法正确实现。 当您将
a(0)
分配给
b
时,请提前感谢它们都指向内存中的同一对象。即使您将
b
声明为
New player
,当您将任务分配给现有玩家时,新玩家也会被丢弃

为了向自己证明这一点,尝试相反的方法。更改
b
name
属性,您将看到它反映在
a(0)
name
属性中

现在克隆

Class player
    Implements ICloneable
    Public name As String
    '[more]
    Public Function Clone() As Object Implements ICloneable.Clone
        Dim p As New player
        p.name = name
        Return p
    End Function
End Class
您的类现在通过添加
Clone
函数实现了
ICloneable
。只要函数的签名与
Clone
方法的接口签名相匹配,您就可以按照自己的意愿实现此功能

请注意,我的实现正在创建一个
新的
播放器,并将
名称
属性分配给现有播放器的
名称
。这个新的播放器是函数返回的。新玩家将在内存中有不同的位置,因此更改列表中的第一个玩家和该新玩家不会相互影响

由于
Clone
函数返回一个对象,我们需要将它强制转换为
player
(底层类型),这样它将匹配
b
的声明,并且我们将能够使用
player
类的属性和方法

Private Sub OPCode()
    Dim a As New List(Of player)
    Dim b As player
    a.Add(New player)
    a(0).name = "john"
    b = CType(a(0).Clone, player)
    a(0).name = "jack"
    MsgBox(b.name) 'john
End Sub
编辑

为了使用两个列表实现您的目标,我创建了一个名为
PlayerList
的新类。它继承
列表(玩家)
并实现
ICloneable
。现在,您可以克隆列表
a
,并获得由独立玩家对象组成的完全独立的列表

Public Class PlayerList
    Inherits List(Of player)
    Implements ICloneable
    Public Function Clone() As Object Implements ICloneable.Clone
        Dim newList As New PlayerList
        For Each p As player In Me
            Dim newP = CType(p.Clone(), player)
            newList.Add(newP)
        Next
        Return newList
    End Function
End Class

Private Sub OPCode()
    Dim a As New PlayerList()
    Dim b As PlayerList
    a.Add(New player)
    a(0).name = "john"
    b = CType(a.Clone, PlayerList)
    a(0).name = "jack"
    MsgBox(b(0).name)
End Sub

与C#一样,VB.NET中的赋值不会复制/克隆/复制对象。
a
b
都是指赋值后的同一对象。也就是说,变量引用同一个集合,并且第一个元素(隐式地)也是同一个播放器。.期望的行为可能是“克隆集合中的所有对象”,尽管还不完全清楚共享对象的哪一部分易变性是一个问题。使
b=a
成为一个问题是没有意义的。a是球员名单,b是球员。你是说
b=a(0)
?@Mary这是我的错。a和b都很感谢你。看起来我几乎是对的,但有些事情我错了,但现在这一切对我来说更有意义,而且它按预期的方式工作。那么我想知道,你能做到吗?如果a和b都是玩家的
列表
,或者更容易将其放入循环中,
b(i)=a(i)。克隆
?@单色你不能做
b=a.clone
,因为
List(of t)
没有实现
iclonable
。但是,如果
a
是某个类型的实例,而该类型本身实现了
ICloneable
,则您可以这样做。@单色请参阅我答案的编辑部分。
Public Class PlayerList
    Inherits List(Of player)
    Implements ICloneable
    Public Function Clone() As Object Implements ICloneable.Clone
        Dim newList As New PlayerList
        For Each p As player In Me
            Dim newP = CType(p.Clone(), player)
            newList.Add(newP)
        Next
        Return newList
    End Function
End Class

Private Sub OPCode()
    Dim a As New PlayerList()
    Dim b As PlayerList
    a.Add(New player)
    a(0).name = "john"
    b = CType(a.Clone, PlayerList)
    a(0).name = "jack"
    MsgBox(b(0).name)
End Sub