我知道我们应该使用字典而不是哈希表。但我找不到一种复制字典的方法。即使将其强制转换为ICollection以获取SyncRoot,也不行,而这也被认为是不好的。
我现在正在进行更改。我的正确假设是,在泛型中无法实现任何类型的克隆,这就是为什么不支持字典克隆的原因吗?
我知道我们应该使用字典而不是哈希表。但我找不到一种复制字典的方法。即使将其强制转换为ICollection以获取SyncRoot,也不行,而这也被认为是不好的。
我现在正在进行更改。我的正确假设是,在泛型中无法实现任何类型的克隆,这就是为什么不支持字典克隆的原因吗?
使用接受字典参数的构造函数。请参考此例:
var dict = new Dictionary<string, string>();
dict.Add("SO", "StackOverflow");
var secondDict = new Dictionary<string, string>(dict);
dict = null;
Console.WriteLine(secondDict["SO"]);
只是为了好玩...你可以使用LINQ!这是一种更通用的方法。
var secondDict = (from x in dict
select x).ToDictionary(x => x.Key, x => x.Value);
编辑
这应该适用于引用类型,我尝试了以下代码:
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"。
IDictionary
的IEqualityComparer
,即如果您有一个具有StringComparer.OrdinalIgnoreCase
的IDictionary
。 - Dennisdict["First"].Name
,在 secondDict["First"].Name
中也会被改变。从一个集合中删除它并不等同于修改它。另外,如果你要使用 Linq:只需使用 dict.ToDictionary
而不是 (from x in dict select x).ToDictionary
。 - drzausImports 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)
如果有人需要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)
对于VB.NET,我发现了一个更简单的解决方案:
dim seconddic as Dictionary(of string,string) = new Dictionary(of string,string)(originaldic)
最简单的方法:
Dictionary<string, int> oldDictionary = new Dictionary<string, int>();
Dictionary<string, int> newDictionary = new Dictionary<string, int>(oldDictionary);
Dim updatedRecord As New Dictionary(Of String, String)(Record)
。 - user10191234对于简单的Dictionary<String, Object>
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;
}
对于原始类型的字典
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
对于实现ICloneable接口的对象字典
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