Creating a "backup" of a Dictionary

J

JamesB

I have a config screen in my app that updates a dictionary<key,value>.

I want to store a copy of this before going into the config screen so if the
user wants to cancel all their changes I can simply set the working copies
to be the backup.

So, in my code, before the config screen is shown, I do this:

Dictionary<string, myClass> TempDic = MainDic;

But when the config screen returns from the showdialog, and the "main"
dictionary has been added to, the temp one has also been added to?
How can I create a copy that doesn't change? Bit confused!
 
P

Peter Duniho

JamesB said:
I have a config screen in my app that updates a dictionary<key,value>.

I want to store a copy of this before going into the config screen so if
the user wants to cancel all their changes I can simply set the working
copies to be the backup.

So, in my code, before the config screen is shown, I do this:

Dictionary<string, myClass> TempDic = MainDic;

But when the config screen returns from the showdialog, and the "main"
dictionary has been added to, the temp one has also been added to?
How can I create a copy that doesn't change? Bit confused!

All that the line you posted does is copy the _reference_ from one
variable to another. The reference refers to the same instance of the
Dictionary<>.

What you need is a method that will create a whole new instance of the
Dictionary<>. I don't believe this is built into the Dictionary<> class
(some classes implement ICloneable, but Dictionary<> doesn't), but you
can easily do it yourself using the generic ICollection<>.CopyTo() method:

Dictionary<string, myClass> Clone(Dictionary<string, myClass> dict)
{
KeyValuePair<string, myClass>[] rgkvp =
new KeyValuePair<string, myClass>(dict.Count);
Dictionary<string, myClass> dictNew = new Dictionary<string,
myClass>(dict.Count);

dict.CopyTo(rgkvp, 0);

foreach (KeyValuePair<string, myClass> kvp in rgkvp)
{
dictNew.Add(kvp.Key, kvp.Value);
}

return dictNew;
}

Hope that helps.

Pete
 
J

JamesB

Peter Duniho said:
JamesB said:
I have a config screen in my app that updates a dictionary<key,value>.

I want to store a copy of this before going into the config screen so if
the user wants to cancel all their changes I can simply set the working
copies to be the backup.

So, in my code, before the config screen is shown, I do this:

Dictionary<string, myClass> TempDic = MainDic;

But when the config screen returns from the showdialog, and the "main"
dictionary has been added to, the temp one has also been added to?
How can I create a copy that doesn't change? Bit confused!

All that the line you posted does is copy the _reference_ from one
variable to another. The reference refers to the same instance of the
Dictionary<>.

What you need is a method that will create a whole new instance of the
Dictionary<>. I don't believe this is built into the Dictionary<> class
(some classes implement ICloneable, but Dictionary<> doesn't), but you can
easily do it yourself using the generic ICollection<>.CopyTo() method:

Dictionary<string, myClass> Clone(Dictionary<string, myClass> dict)
{
KeyValuePair<string, myClass>[] rgkvp =
new KeyValuePair<string, myClass>(dict.Count);
Dictionary<string, myClass> dictNew = new Dictionary<string,
myClass>(dict.Count);

dict.CopyTo(rgkvp, 0);

foreach (KeyValuePair<string, myClass> kvp in rgkvp)
{
dictNew.Add(kvp.Key, kvp.Value);
}

return dictNew;
}

Hope that helps.

Pete

Thanks Pete,
Your explanation made complete sense however I couldn't get your code sample
working straight off- firstly the (dict.count) in the first line needed to
be [dict.count] to init the array size I guess, but then it still failed as
"dict" doesn't contain a definition for CopyTo.

I had a play around and came up with a cut down version that seems to work
fine though, so many thanks for your help as it got me in the right
direction!

My Clone method:

Dictionary<string, myClass> Clone(Dictionary<string, myClass> dict)
{
Dictionary<string, myClass> dictNew = new
Dictionary<string,myClass>();

foreach (KeyValuePair<string, myClass> kvp in dict)
{
dictNew.Add(kvp.Key, kvp.Value);
}

return dictNew;
}
 
P

Peter Duniho

JamesB said:
Your explanation made complete sense however I couldn't get your code
sample working straight off- firstly the (dict.count) in the first line
needed to be [dict.count] to init the array size I guess, but then it
still failed as "dict" doesn't contain a definition for CopyTo.

Yeah, sorry. That's what happens when the code is just typed in to the
newsreader. No compiler to help me catch little mistakes like that. :)

The paren-versus-brace issue is obvious and easy to fix, as you have.

The CopyTo() method is actually from the ICollection<> interface and is
explicitly implemented, so you have to cast to an ICollection<> to use
it. However, as you've already discovered, doing the copy is
superfluous since you can just get the KeyValuePairs<> directly from the
Dictionary<> itself.

Not sure why I thought the CopyTo() was necessary, but your Clone()
method is fine. :)

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top