【问题标题】:Deep copying of elements in a List (Of Class)列表(类)中元素的深度复制
【发布时间】:2015-05-31 02:26:35
【问题描述】:

晚上好。

我正在尝试对列表中的某些元素进行深度复制,但我发现它非常难以做到。我正在尝试很多新概念,如果以下代码看起来很奇怪,请耐心等待...

我有以下列表:

accountList as List(Of Account)
accountsInArea as New List(Of Account)
result as New List(Of Account)

其中每个元素的类型都是我自己定义的 Class:

Public Class Account

Enum AddingType
    income
    expenditure
End Enum
Enum AreaType
    high
    mid
    low
End Enum

Property Area() As AreaType
Property Group() As String
Property AccountNumber() As Integer
Property AccountDescription() As String
Property IncomeExpenditure() As AddingType
Public Property MonthlyValues As New Dictionary(Of Integer, Decimal)
End Class

我需要找到accountList 的某些 项并将值 复制到一个新列表:accountsInArea。目前,我使用了以下方法:

accountsInArea = accountList.FindAll(Function(acc) acc.Area = area)

但是,这会生成 Lambda 表达式生成的那些项目的 reference 副本(不是吗?)。如果我在浏览 SO 和 MSDN 时理解正确,我需要的是元素的深拷贝。

我希望accountsInArea 拥有.FindAll 生产的所有项目的副本,包括(尤其是)MonthlyValuesDictionary 中的项目。

我试过了:

accountsInArea = accountList.Select(accountList.FindAll(Function(acc) acc.Area = area))

还有:

For Each account In accountList.FindAll(Function(acc) acc.Area = area)
    accountsInArea.Add(account)
Next

最后添加到类中:

Implements ICloneable

Public Function Clone() As Object Implements System.ICloneable.Clone
    Return Me.MemberwiseClone
End Function

并在方法内部使用:

accountsInArea = accountList.FindAll(Function(acc) acc.Area = area)
    result = accountsInArea.Select(Function(acc) acc.Clone()).Cast(Of Account).ToList

非常感谢您的帮助。

【问题讨论】:

    标签: vb.net list class clone deep-copy


    【解决方案1】:

    只需在您的类中实现 ICloneable,然后

    Dim accountsInArea As List(Of Account) = accountList.Where(Function(x) x.Area = Account.AreaType.high).Select(Function(y) y.clone).Cast(Of Account)().ToList
    

    这里是你前任的完整代码

    Sub AccountListProg
        Dim accountList As New List(Of Account) From {New Account With {.Area = Account.AreaType.high, .AccountNumber = 1}, _
                                                       New Account With {.Area = Account.AreaType.high, .AccountNumber = 2}, _
                                                       New Account With {.Area = Account.AreaType.low, .AccountNumber = 3}, _
                                                       New Account With {.Area = Account.AreaType.mid, .AccountNumber = 4}}
    
        Dim accountsInArea As List(Of Account) = accountList.Where(Function(x) x.Area = Account.AreaType.high).Select(Function(y) y.clone).Cast(Of Account)().ToList
    End Sub
    
    Public Class Account
        Implements ICloneable
        Public Function Clone() As Object Implements ICloneable.Clone
            Return New Account With {.AccountDescription = AccountDescription, _
                                 .AccountNumber = AccountNumber, _
                                 .Area = Area, _
                                 .Group = Group, _
                                 .IncomeExpenditure = AddingType.income, _
                                 .MonthlyValues = MonthlyValues}
        End Function
        Enum AddingType
            income
            expenditure
        End Enum
        Enum AreaType
            high
            mid
            low
        End Enum
    
        Property Area() As AreaType
        Property Group() As String
        Property AccountNumber() As Integer
        Property AccountDescription() As String
        Property IncomeExpenditure() As AddingType
        Public Property MonthlyValues As New Dictionary(Of Integer, Decimal)
    End Class
    

    【讨论】:

    • 看起来比将克隆逻辑留在课堂之外更好!不错的死灵,不过:P
    【解决方案2】:

    经过一番修改后,我找到了解决方案。虽然我确信有更优雅的东西,但我会在这里发布以防万一有人急需:

    我最终在方法中使用了以下代码:

    Dim accountsInArea as New List(Of Account)
    
    For Each account In accountList.FindAll(Function(acc) acc.Area = area)
        Dim a As New Account
        With a
            .Area = account.Area
            .AccountDescription = account.AccountDescription
            .Group = account.Group
            .IncomeExpenditure = account.IncomeExpenditure
            .AccountNumber = account.AccountNumber
            .MonthlyValues = New Dictionary(Of Integer, Decimal)
        End With
        For Each val In account.MonthlyValues
            Dim k As Integer = v.Key
            Dim v As Decimal = v.Value
            a.MonthlyValues.Add(k, v)
        Next
        accountsInArea.Add(a)
    Next
    

    因此,如果有人知道一种不太复杂的方法(可能涉及我在问题中提到的一种方法),那就太棒了。

    还是谢谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-15
      • 2012-10-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多