如何在.NET中克隆词典?

如何在.NET中克隆词典?,.net,data-structures,.net,Data Structures,我知道我们应该使用字典而不是哈希表。但是我找不到克隆这本词典的方法。即使将它投射到我为获得SyncRoot而做的ICollection,我知道这也是不受欢迎的 我现在正忙着改变。我是否有一个正确的假设,即没有办法以通用的方式实现任何类型的克隆,这就是为什么字典不支持克隆?这是我曾经写过的一个快速而肮脏的克隆方法……我认为最初的想法来自CodeProject Imports System.Runtime.Serialization Imports System.Runtime.Serializat

我知道我们应该使用字典而不是哈希表。但是我找不到克隆这本词典的方法。即使将它投射到我为获得SyncRoot而做的ICollection,我知道这也是不受欢迎的


我现在正忙着改变。我是否有一个正确的假设,即没有办法以通用的方式实现任何类型的克隆,这就是为什么字典不支持克隆?

这是我曾经写过的一个快速而肮脏的克隆方法……我认为最初的想法来自CodeProject

Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary

Public Shared Function Clone(Of T)(ByVal inputObj As T) As T
    'creating a Memorystream which works like a temporary storeage '
    Using memStrm As New MemoryStream()
        'Binary Formatter for serializing the object into memory stream '
        Dim binFormatter As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        'talks for itself '
        binFormatter.Serialize(memStrm, inputObj)

        'setting the memorystream to the start of it '
        memStrm.Seek(0, SeekOrigin.Begin)

        'try to cast the serialized item into our Item '
        Try
            return DirectCast(binFormatter.Deserialize(memStrm), T)
        Catch ex As Exception
            Trace.TraceError(ex.Message)
            return Nothing
        End Try
    End Using
End Function
用途:

Dim clonedDict As Dictionary(Of String, String) = Clone(Of Dictionary(Of String, String))(yourOriginalDict)

使用接受字典的构造函数。看这个例子

var dict = new Dictionary<string, string>();

dict.Add("SO", "StackOverflow");

var secondDict = new Dictionary<string, string>(dict);

dict = null;

Console.WriteLine(secondDict["SO"]);
编辑

这应该适用于引用类型,我尝试了以下方法:

internal class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public User Parent { get; set; }
}
以及上面修改的代码

var dict = new Dictionary<string, User>();

dict.Add("First", new User 
    { Id = 1, Name = "Filip Ekberg", Parent = null });

dict.Add("Second", new User 
    { Id = 2, Name = "Test test", Parent = dict["First"] });

var secondDict = (from x in dict
                  select x).ToDictionary(x => x.Key, x => x.Value);

dict.Clear();

dict = null;

Console.WriteLine(secondDict["First"].Name);

它输出了Filip Ekberg.

,因为任何人都需要vb.net版本

Dim dictionaryCloned As Dictionary(Of String, String)
dictionaryCloned  = (From x In originalDictionary Select x).ToDictionary(Function(p) p.Key, Function(p) p.Value)

对于基本类型字典

Public Sub runIntDictionary()
  Dim myIntegerDict As New Dictionary(Of Integer, Integer) From {{0, 0}, {1, 1}, {2, 2}}
  Dim cloneIntegerDict As New Dictionary(Of Integer, Integer)
  cloneIntegerDict = myIntegerDict.Select(Function(x) x.Key).ToList().ToDictionary(Of Integer, Integer)(Function(x) x, Function(y) myIntegerDict(y))
End Sub
对于实现iClonable的对象的字典

Public Sub runObjectDictionary()
  Dim myDict As New Dictionary(Of Integer, number) From {{3, New number(3)}, {4, New number(4)}, {5, New number(5)}}
  Dim cloneDict As New Dictionary(Of Integer, number)
  cloneDict = myDict.Select(Function(x) x.Key).ToList().ToDictionary(Of Integer, number)(Function(x) x, Function(y) myDict(y).Clone)
End Sub

Public Class number
  Implements ICloneable
  Sub New()
  End Sub
  Sub New(ByVal newNumber As Integer)
    nr = newnumber
  End Sub
  Public nr As Integer

  Public Function Clone() As Object Implements ICloneable.Clone
    Return New number With {.nr = nr}
  End Function
  Public Overrides Function ToString() As String
    Return nr.ToString
  End Function
End Class
简单词典


看,我看到了,但我不在乎深度复制。克隆浅拷贝就可以了。我的问题还有第二部分,那就是:没有克隆的原因是因为泛型引入了困难吗?请记住,第一种方法将创建一个浅拷贝,即对象也不会被复制。对于不是真正问题的字符串,但对于其他引用类型,它可能是。对于LINQ表达式,它至少应该复制引用。当GC查找dict时,它是空的,但引用不是空的,它们不应该被删除,对吗?因此,它也应该适用于引用类型。值得注意的是:这种方法不会克隆源IDictionary的IEqualityComparer,也就是说,如果您的IDictionary带有StringComparer.OrdinalIgnoreCase。第一个示例也不应该说dict=null;但是dict.clear;要真正证明新的引用不仅仅是引用。您的引用示例具有误导性/不正确-引用的类型在两个集合中仍然是相同的实例:-更改dict[First].Name,并且它也将在secondDict[First].Name中更改。从一个集合中删除它与修改它不是一回事。另外,如果要使用Linq:just dict.ToDictionary而不是dict中的from x,请选择x.ToDictionary。
Public Sub runObjectDictionary()
  Dim myDict As New Dictionary(Of Integer, number) From {{3, New number(3)}, {4, New number(4)}, {5, New number(5)}}
  Dim cloneDict As New Dictionary(Of Integer, number)
  cloneDict = myDict.Select(Function(x) x.Key).ToList().ToDictionary(Of Integer, number)(Function(x) x, Function(y) myDict(y).Clone)
End Sub

Public Class number
  Implements ICloneable
  Sub New()
  End Sub
  Sub New(ByVal newNumber As Integer)
    nr = newnumber
  End Sub
  Public nr As Integer

  Public Function Clone() As Object Implements ICloneable.Clone
    Return New number With {.nr = nr}
  End Function
  Public Overrides Function ToString() As String
    Return nr.ToString
  End Function
End Class
public static Dictionary<string, object> DictionaryClone(Dictionary<string, object> _Datas)
{
    Dictionary<string, object> output = new Dictionary<string, object>();

    if (_Datas != null)
    {
        foreach (var item in _Datas)
            output.Add(item.Key, item.Value);
    }

    return output;
}