【问题标题】:Make a deep copy of a dictionary制作字典的深层副本
【发布时间】:2015-02-07 14:14:59
【问题描述】:

我有一个名为 baseDictionary 的字典。键是字符串,值是名为 myData 的类的属性。特别是这些属性是:“age”(作为 int)、“nationality”(作为字符串)和“income”(作为 double)。

所以 baseDictionary 有一些字符串作为键,每个键都有一系列与特定人相关的属性。 我想在某个时候制作这本字典的深层副本,这样我就可以在不修改原始字典内容的情况下使用这个新副本。 我在 stackoverflow 中找到了一个答案,建议使用以下代码来执行此深层复制:

public static Dictionary<TKey, TValue>
     CloneDictionaryCloningValues<TKey, TValue>(
         Dictionary<TKey, TValue> original) where TValue : ICloneable
{
    Dictionary<TKey, TValue> ret = new Dictionary<TKey, TValue>(
         original.Count, original.Comparer);

    foreach (KeyValuePair<TKey, TValue> entry in original)
    {
        ret.Add(entry.Key, (TValue) entry.Value.Clone());
    }
    return ret;
}

问题是我不明白我应该如何修改它以使其与我的字典一起使用。例如我试过:

public static Dictionary<string, myData> CloneDictionaryCloningValues<TKey, TValue>
                    (Dictionary<string, myData> original) where TValue : ICloneable
    {
        Dictionary<string, myData> ret = new Dictionary<string, myData>(original.Count,
                                                                original.Comparer);
        foreach (KeyValuePair<string, myData> entry in original)
        {
            ret.Add(entry.Key, (myData)entry.Value.Clone());
        }
        return ret;
    }

但是我收到以下错误并且它不起作用。

错误 3 'Project2.myData 不包含 'Clone' 的定义,并且没有扩展方法 'Clone' 接受类型的第一个参数 'Project2.myData 可以找到(您是否缺少 using 指令或 程序集参考?)

我该如何解决这个问题?

【问题讨论】:

    标签: c# dictionary copy


    【解决方案1】:

    你根本不需要改变CloneDictionaryCloningValues方法,如果你让myData类实现ICloneable接口:

    public class myData : ICloneable {
    
      // your code
    
      public object Clone() {
        // whatever you need to create a copy, for example:
        return new myData() {
          age = this.age,
          nationality = this.nationality,
          income = this.income
        };
      }
    
    }
    

    您还可以重写/重载方法以采用克隆方法,而不是要求IClonable 接口:

    public static Dictionary<TKey, TValue> CloneDictionaryCloningValues<TKey, TValue>
       (Dictionary<TKey, TValue> original, Func<TValue, TValue> clone)
    {
      Dictionary<TKey, TValue> ret = new Dictionary<TKey, TValue>(original.Count, original.Comparer);
      foreach (KeyValuePair<TKey, TValue> entry in original) {
        ret.Add(entry.Key, clone(Value));
      }
      return ret;
    }
    

    然后您使用创建项目副本的函数调用该方法:

    myCopy = CloneDictionaryCloningValues(myOriginal, item => {
      // whatever you need to create a copy, for example:
      return new myData() {
        age = item.age,
        nationality = item.nationality,
        income = item.income
      };
    });
    

    【讨论】:

    • 感谢您向我展示如何修改类以实现 iCloneable。我只需要使用 ICloneable (只是一个错字)和其他一些东西来修改 IClonable 以使其工作。谢谢。
    【解决方案2】:

    您不应该修改CloneDictionaryCloningValues() 例程,直接使用它即可。因为它是通用的,所以它可以与您的键(字符串)和值类(mydata)一起使用。

    但是:

    要使这个例程工作,你的类必须有一个公共的Clone() 例程,即实现ICloneable 接口。

    【讨论】:

    • 你的意思是在 myData.cs 中吗?
    • @mickG 在 MSDN 上的 ICloneable 上查找
    【解决方案3】:

    正如函数指定的:你需要在myData类型上实现ICloneable

    还有:

    • 保留原始代码并简单地传递您的字典。
    • myData 类重命名为更具描述性的名称,并以大写字符开头

    【讨论】:

      猜你喜欢
      • 2013-06-30
      • 2016-01-29
      • 1970-01-01
      • 2022-12-13
      • 2015-12-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多