Link to home
Start Free TrialLog in
Avatar of nightshadz
nightshadzFlag for United States of America

asked on

C# Copy/Clone Dictionary

How do I easily copy/clone the dictionary in employeeAudit[0] to employeeAudit[1]?

        static void Main(string[] args)
        {
            XElement doc = XElement.Load(AppConfig.GetPositionFile());

            List<EmployeeAudit> employeeAudit = new List<EmployeeAudit>();
            
            XElement e = doc.Element("entry");
            employeeAudit.Add(new EmployeeAudit());
            employeeAudit[0].Field("Timestamp",e.Attribute("timestamp").Value);
            employeeAudit[0].Field("Effective",e.Attribute("effective").Value);

            employeeAudit.Add(new EmployeeAudit());
            employeeAudit[1] = employeeAudit[0]; 
            employeeAudit[1].Field("Timestamp", "19551005");

        }       

    class EmployeeAudit
    {
        private Dictionary<string, string> Fields = new Dictionary<string,string>();

        public void Field(string fieldName, string fieldValue)
        {
            Fields[fieldName] = fieldValue;
        }
    }

Open in new window

SOLUTION
Avatar of Kyle Abrahams, PMP
Kyle Abrahams, PMP
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of nightshadz

ASKER

Apologies, I wasn't clear in my original question and thought he source code would be enough...

employeeAudit is a List of Type EmployeeAudit

I want to create a copy of the EmployeeAudit class, not a reference, for

employeeAudit[1] = employeeAudit[0];
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Personally, just to add to Miguel's comment, I'd suggest calling the method "DeepClone" or "DeepCopy", so that it clearly expresses that the resulting object is just that.
Awesome! Thank you!!

kaufmed & miguel - Just to further my education, this doesn't really implement ICloneable, correct? It's kind of just filling a new dictionary and returning it as type EmployeeAudit.

I've looked at some examples that implement ICloneable but it's still a new concept to me. Would implementing ICloneable  do the same thing since I have to implement the Clone method regardless?  

What's cleaner or a 'best practice'? Writing my own clone method or using ICloneable?
The ICloneable interface is a highly debated topic. You'll see arguments on both sides that say its Clone method represents a shallow or deep copy. In the end, there's nothing forcing you to attach the ICloneable interface to your class simply because it has a Clone method. Attaching the interface would provide you with a level of abstraction, though, that could help you in other bits of your code. You would need to gauge if there's enough benefit for you to do so. If you do decide to implement the interface, then at the very least be consistent in how you implement it--if one class does a deep copy, then so should all the other classes which implement that interface, and vice versa. If this is a library that will be consumed by other applications (i.e. other developers), then you should clearly document what your Clone methods do.

Personally, I've always thought a "clone" as a deep copy. When Dolly was cloned, you didn't see two conjoined sheep running around--she was a distinct being herself.
Interesting. Doing a little more digging a came across this wiki article http://en.wikipedia.org/wiki/Object_copy and have a better understanding of what is going on now, I hope. To clarify, the code above that Miguel provided would be considered a deep copy since the old and new are referencing different objects in memory - this would be considered a deep copy since modifying any attribute of a would never affect b?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you so much for all the information!

While mucking around, I attempted to implement the code Kyle first posted and got it working. I merged it into the Clone method as follows:

        //Deep copy the Fields dictionary
        public Audit Clone()
        {
            Audit cloned = new Audit();
            //cloned.Fields = new Dictionary<string, string>(this.Fields);

            cloned.Fields = this.Fields.ToDictionary(i => i.Key, i => i.Value);
            return cloned;
        }

Open in new window


While it achieves the same result, it doesn't seem like it's the most efficient since it loops over every item in the dictionary. Correct me if I'm wrong please?