That is correct. Session (InProc) , Cache and Application all return "live" references. A good writeup on this can be found by friend and fellow MVP Rick Strahl here:
http://www.west-wind.com/Weblog/posts/1214.aspx
If you do not want this behavior, you need to either delete the Session / Cache / Application object and replace it with what you want later, or store a clone by duplicating the object, doing your work on the original that you got out of Cache, then replacing the existing cached item with your clone that was not changed.
for example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace CachebyRef
{
public class Person
{
public String FirstName { get; set; }
public String LastName { get; set; }
}
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Listlist = new List ();
list.Add(new Person(){FirstName="Joe",LastName = "Blow"});
Cache["personList"] = list;
ListnewList = (List ) Cache["personList"];
Person p = newList[0];
Response.Write(p.FirstName + ": " + p.LastName + "<br/>");
p.FirstName = "Altered";
p.LastName = "State";
ListaltList = (List ) Cache["personList"];
Person q = altList[0];
// Surprise - the cached item contains the change:
Response.Write(q.FirstName + ": " + q.LastName);
}
}
}