{"id":778,"date":"2014-08-31T17:55:54","date_gmt":"2014-08-31T21:55:54","guid":{"rendered":"http:\/\/www.peteonsoftware.com\/?p=778"},"modified":"2024-03-01T17:42:55","modified_gmt":"2024-03-01T22:42:55","slug":"c-memberwiseclone","status":"publish","type":"post","link":"https:\/\/www.peteonsoftware.com\/index.php\/2014\/08\/31\/c-memberwiseclone\/","title":{"rendered":"C# MemberwiseClone"},"content":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/www.peteonsoftware.com\/images\/201408\/Clone.jpg\" alt=\"Clone Trooper - Creative Commons License from https:\/\/c2.staticflickr.com\/4\/3484\/3796528975_e8c7faaed2_z.jpg?zz=1\" title=\"Clone Trooper - Creative Commons License from https:\/\/c2.staticflickr.com\/4\/3484\/3796528975_e8c7faaed2_z.jpg?zz=1\" style=\"float:left; margin:.5em\" \/><\/p>\n<p>If you&#8217;ve ever needed to make a copy of an object in C#, you might have come across the MemberwiseClone() method.  This can save you a lot of hassle of left-hand\/right-hand property matching, but it does come with some &#8220;gotchas&#8221; that might not be readily apparent if you haven&#8217;t carefully read the documentation.<\/p>\n<p>Let&#8217;s start with a class that looks like this.  Notice that it has a ShallowCopy method that just returns a MemberwiseClone of the object.<\/p>\n<pre>\r\npublic class Person\r\n    {\r\n        public string Name { get; set; }\r\n        public Person Boss { get; set; }\r\n\r\n        public Person ShallowCopy()\r\n        {\r\n            return (Person)this.MemberwiseClone();\r\n        }\r\n    }\r\n<\/pre>\n<p>Now, let&#8217;s create some objects and make a shallow copy of the worker and see if the objects are the same:<\/p>\n<pre>\r\nPerson bigBoss = new Person() { Name = \"Tony\", Boss = null };\r\nPerson boss = new Person() { Name = \"Silvio\", Boss = bigBoss };\r\nPerson worker = new Person() { Name = \"Paulie\", Boss = boss };\r\n\r\nPerson cloneWorker = worker.ShallowCopy();\r\nConsole.WriteLine(\"Are the workers the same? {0}\", worker.Equals(cloneWorker));\r\nConsole.WriteLine(\"Are the bosses the same? {0}\", worker.Boss.Equals(cloneWorker.Boss));\r\n<\/pre>\n<p>This gives us the following results:<\/p>\n<pre>\r\nAre the workers the same? False\r\nAre the bosses the same? True\r\n<\/pre>\n<p>&#8220;So what?&#8221; you might ask.  Well, what that means is that if I change a property on the Boss of either object, it automatically changes in the other object (since only the reference was copied, and that reference points to the same memory address in both cases).<\/p>\n<pre>\r\nworker.Boss.Name = \"Chuck\";\r\nConsole.WriteLine(\"Worker's Boss' Name: {0}.\", worker.Boss.Name);\r\nConsole.WriteLine(\"Clone Worker's Boss' Name: {0}.\", cloneWorker.Boss.Name);\r\n<\/pre>\n<p>This gives us the output:<\/p>\n<pre>\r\nWorker's Boss' Name: Chuck.\r\nClone Worker's Boss' Name: Chuck.\r\n<\/pre>\n<p>It is possible that you may be okay with this happening.  However, if you don&#8217;t want this to happen, you can implement a DeepCopy on your object instead.  In the DeepCopy, you take a MemberwiseClone and then you call for a deep copy on every reference type in the object.  In our example, I&#8217;d add this to our Person class:<\/p>\n<pre>\r\npublic Person DeepCopy()\r\n{\r\n    Person copy = (Person)this.MemberwiseClone();\r\n\r\n    if (this.Boss != null)\r\n    {\r\n        copy.Boss = this.Boss.DeepCopy();\r\n    }\r\n\r\n    return copy;\r\n}\r\n<\/pre>\n<p>Now, when I check on the objects, they aren&#8217;t the same.  And, when we change the property on the boss, it doesn&#8217;t automatically change in both places because they are completely separate objects.<\/p>\n<pre>\r\nAre the workers the same? False\r\nAre the bosses the same? False\r\n\r\nWorker's Boss' Name: Chuck.\r\nClone Worker's Boss' Name: Silvio.\r\n<\/pre>\n<p>That&#8217;s all there is to it.  I have wrapped up the code for this blog post into a small console project and <a href=\"https:\/\/github.com\/PeteShearer\/MemberwiseCloneExample\">put it on GitHub<\/a>.  If you have any questions, let me know in the comments.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you&#8217;ve ever needed to make a copy of an object in C#, you might have come across the MemberwiseClone() method. This can save you a lot of hassle of left-hand\/right-hand property matching, but it &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15],"tags":[89],"class_list":["post-778","post","type-post","status-publish","format-standard","hentry","category-code-tips","tag-code-tips"],"_links":{"self":[{"href":"https:\/\/www.peteonsoftware.com\/index.php\/wp-json\/wp\/v2\/posts\/778","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.peteonsoftware.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.peteonsoftware.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.peteonsoftware.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.peteonsoftware.com\/index.php\/wp-json\/wp\/v2\/comments?post=778"}],"version-history":[{"count":0,"href":"https:\/\/www.peteonsoftware.com\/index.php\/wp-json\/wp\/v2\/posts\/778\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.peteonsoftware.com\/index.php\/wp-json\/wp\/v2\/media?parent=778"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.peteonsoftware.com\/index.php\/wp-json\/wp\/v2\/categories?post=778"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.peteonsoftware.com\/index.php\/wp-json\/wp\/v2\/tags?post=778"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}