views:

94

answers:

2

Hi,

I am using C# and ASP.NET 3.5.

I stored a generic list in HttpContext.Current.Application so that all the pages of a website can have access to it. When I assign its value to a local variable on a local page for some local use, any change I make to the local variable gets reflected back in the original list in the Application State. It is as if a direct reference to the Application state variable is being made when I assign it locally.

Here is some sample code that instantiates a local generic list variable, adds 3 strings to the variable, adds the variable to the application state, removes one item from the local variable, and prints out the count along the way. The result is that the one item removed from the local variable is also removed from the corresponding list in the application state.

    -- generic list in Application state
    Response.Write("<BR><BR><b>list (generic) example in Application</b><BR><BR>");
    List<string> productList = new List<string>();
    productList.Add("1");
    productList.Add("2");
    productList.Add("3");
    HttpContext.Current.Application["productList"] = productList;
    Response.Write("product segments: " + productList.Count + "<BR>");
    Response.Write("product segments in application cache: " + ((List<string>)HttpContext.Current.Application["productList"]).Count + "<BR>");

    productList.Remove("1");

    Response.Write("product segments: " + productList.Count + "<BR>");
    Response.Write("product segments in application cache: " + ((List<string>)HttpContext.Current.Application["productList"]).Count + "<BR>");

Feel free to run this code in an aspx file and see the results for yourself.

Question: how can you store generics in the Application state so that they can be assigned to local variables and a change to that local variable should not propagate back to the Application state variable?

By the way, this is also happening in the Session state. What am I missing with storing generics in Application or Session?

Thank you for your help.

Rahim

A: 

Try something like:

List<string> localList = new List<string>((List<string>)HttpContext.Current.Application["productList"]);

In your version you are in fact modifying the stored product list through a local reference variable. You need to create a local copy of the list (which the above code does) if you don't want changes to propagate back to the main list.

MartinStettner
I thought about doing this, but just didn't know why I needed to. Thanks for your help.
Rahim Snow
+1  A: 

Your problem is that List is a reference type, so when you assign productList to the Context...you're really only adding a reference to the original list. That's why changes appear in both location.

You need to clone the list rather than just assign the existing list to the Context. Depending on whether or not you need a shallow copy vs. a deep copy you can use the following code:

HttpContext.Current.Application["productList"] = 
    new List<string>(productList);

or

HttpContext.Current.Application["productList"] = 
    new List<string>(productList.Select(item => item.Clone()).ToList());
Justin Niessner
Thank you, that made things click in my head.
Rahim Snow