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. I am busy changing that now. I am 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?
A:
This is a quick and dirty clone method I once wrote...the initial idea is from CodeProject, I think.
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)
Bobby
2010-02-17 09:54:27
+3
A:
Use the Constructor that takes a Dictionary. See this example
var dict = new Dictionary<string, string>();
dict.Add("SO", "StackOverflow");
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.
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
2010-02-17 09:56:15
Just keep in mind that the first approach will create a shallow copy, i.e. the objects are not copied as well. For strings that is not really an issue but for other reference types it may be.
Brian Rasmussen
2010-02-17 10:05:25
With the LINQ-expression it should at least copy the references. And when the GC find dict and it's null, but the references are not, they shoulndn't be removed, am i right? So it _should_ work on reference types aswell.
Filip Ekberg
2010-02-17 10:09:10
A:
This is a code project page on doing a deep clone of a dictionary. http://www.codeproject.com/KB/recipes/DeepCloneDictionary.aspx?display=Print
btlog
2010-02-17 09:57:47