你如何在.NET中克隆字典?

时间:2021-06-17 13:13:05

I know that we should rather be using dictionaries as opposed to hashtables. I cannot find a way to clone the dictionary though. Even if casting it to ICollection which I do to get the SyncRoot, which I know is also frowned upon.

我知道我们应该使用字典而不是哈希表。我找不到克隆字典的方法。即使将它转换为ICollection,我也是为了获得SyncRoot,我知道这也是不满意的。

I am busy changing that now. Am I under the correct assumption that there is no way to implement any sort of cloning in a generic way which is why clone is not supported for dictionary?

我现在忙着改变它。我是否正确地假设无法以通用方式实现任何类型的克隆,这就是字典不支持克隆的原因?

2 个解决方案

#1


56  

Use the Constructor that takes a Dictionary. See this example

使用带有Dictionary的构造函数。看这个例子

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

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

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

dict = null;

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

And just for fun.. You can use LINQ! Which is a bit more Generic approach.

只是为了好玩..你可以使用LINQ!这是一种更通用的方法。

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

Edit

编辑

This should work well with Reference Types, I tried the following:

这应该适用于参考类型,我尝试了以下内容:

internal class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public User Parent { get; set; }
}

And the modified code from above

以及上面的修改代码

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);

Which outputs "Filip Ekberg".

其中输出“Filip Ekberg”。

#2


2  

This is a quick and dirty clone method I once wrote...the initial idea is from CodeProject, I think.

这是我曾经写过的一种快速而又脏的克隆方法......我认为最初的想法来自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

Useage:

用途:

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

#1


56  

Use the Constructor that takes a Dictionary. See this example

使用带有Dictionary的构造函数。看这个例子

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

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

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

dict = null;

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

And just for fun.. You can use LINQ! Which is a bit more Generic approach.

只是为了好玩..你可以使用LINQ!这是一种更通用的方法。

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

Edit

编辑

This should work well with Reference Types, I tried the following:

这应该适用于参考类型,我尝试了以下内容:

internal class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public User Parent { get; set; }
}

And the modified code from above

以及上面的修改代码

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);

Which outputs "Filip Ekberg".

其中输出“Filip Ekberg”。

#2


2  

This is a quick and dirty clone method I once wrote...the initial idea is from CodeProject, I think.

这是我曾经写过的一种快速而又脏的克隆方法......我认为最初的想法来自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

Useage:

用途:

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