title: Copy/clone an object in Session
body: <p>When I put an instance of a custom class into Session and then pull it out, I need it to come out as a COPY of what's in Session, not a reference to what's in Session.  Here's what I have, watered down for example purposes.</p>
  
  <pre><code>protected void btnSubmit_Click(object sender, EventArgs e)
  {
      Company selectedCompany = new Company("1234"); //a company code
      selectedCompany.AnotherClass.Value1 = "hello";
      Session["OLD.Company"] = selectedCompany;
  
      Company newCompany = (Company)Session["OLD.Company"]; //I want this to be a COPY of what's in Session, not a reference to it.
      newCompany.AnotherClass.Value1 = "goodbye";
      Session["NEW.Company"] = newCompany;
  }
  </code></pre>
  
  <p>I stepped through and watched the Session variables, and the above code results in the AnotherClass.Value1 for BOTH OLD.Company and NEW.Company being set to "goodbye."</p>
  
  <p>Initial Google searches point me in the direction of implementing IClonable on my Company class.  I tried the following, but to no avail:</p>
  
  <pre><code>public class Company : ICloneable
  {
      //properties...
      //constructors...
      public object Clone()
      {
          return this.MemberwiseClone();
      }
  }
  </code></pre>
  
  <p>and then...</p>
  
  <pre><code>protected void btnSubmit_Click(object sender, EventArgs e)
  {
      Company oldCompany = (Company)Session["OLD.Company"];
      Company newCompany = (Company)oldCompany.Clone();
      newCompany.AnotherClass.Value1 = "goodbye";
      Session["NEW.Company"] = newCompany;
  }
  </code></pre>
  
  <p>still results in Value1 for BOTH OLD.Company and NEW.Company being "goodbye".  Now I suspect this is because MemberwiseClone() creates a "shallow" copy, and my problem here is that Value1 is a value in a property which is a reference type (AnotherClass).</p>
  
  <p>But at the same time, I also found <a href="http://blogs.msdn.com/b/brada/archive/2003/04/09/49935.aspx" rel="nofollow">this site</a> which says DO NOT implement ICloneable.  So for my purpose here I'm not really sure what to do/what advice to pursue.</p>
  
  <p>Several other sites I found show some version of this:</p>
  
  <pre><code>public static object CloneObject(object obj)
  {
      using (MemoryStream memStream = new MemoryStream())
      {
          BinaryFormatter binaryFormatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Clone));
          binaryFormatter.Serialize(memStream, obj);
          memStream.Seek(0, SeekOrigin.Begin);
          return binaryFormatter.Deserialize(memStream);
      }
  }
  </code></pre>
  
  <p>This requires that I make my class serializable --- which is probably okay (I'll have to read up on Serialization), but after reading the article about not using ICloneable, I'm not sure if I should invest time in pursuing an ICloneable solution.</p>