Maciek Nawrocki
Maciek Nawrocki

Reputation: 29

Why does modifying one session variable also modify a different session variable?

I have a weird problem. One of my variables is changed via this function (code below). I don't know how it is possible. I want to change Session["p_skok"], but in some way, variable Session["z_skok"] is also changing.

    protected void oblicz_parametry()
    {
        List<string> lista_odnosnik_wartosc = (List<string>)Session["p_wartosc"];
        List<Type> lista_odnosnik_typ = (List<Type>)Session["p_typ"];
        List<bool> lista_odnosnik_inkrementacja = (List<bool>)Session["p_inkrementacja"];
        List<int> lista_odnosnik_nr = (List<int>)Session["p_nr"];
        List<int> lista_odnosnik_skok = (List<int>)Session["p_skok"];

        List<int> lista_odnosnik_skok_pomocnicza = (List<int>)Session["z_skok"];
        if (Session["iteracja"] != null)
        {
            for (int i = 0; i < lista_odnosnik_inkrementacja.Count(); i++)
            {
                if (lista_odnosnik_skok[i] == 0 && lista_odnosnik_inkrementacja[i] == true)
                {
                    int zwieksz = lista_odnosnik_nr[i];
                    //if (lista_odnosnik_typ[i].ToString() == "int")
                    //{
                        int zm_pomocnicza = Convert.ToInt32(lista_odnosnik_wartosc[i]) + lista_odnosnik_nr[i];
                        lista_odnosnik_wartosc[i] = zm_pomocnicza.ToString();
                    //}
                    lista_odnosnik_skok[i] = lista_odnosnik_skok_pomocnicza[i] + 1;
                }
                lista_odnosnik_skok[i]--;
            }
            Session["p_wartosc"] = lista_odnosnik_wartosc;
            Session["p_skok"] = lista_odnosnik_skok;

        }
        else
        {
            Session["iteracja"] = 1;
            Session["p_wartosc"] = Session["z_wartosc"];
            Session["p_inkrementacja"] = Session["z_inkrementacja"];
            Session["p_nr"] = Session["z_nr"];
            Session["p_skok"] = Session["z_skok"];

            oblicz_parametry();

        }
    }

I did some debugging and found out that decreasing happens because of lista_odnosnik_skok[i]--; part of the code. Do you know what might be happening?

Upvotes: 1

Views: 533

Answers (2)

Scott Hannen
Scott Hannen

Reputation: 29207

It's a combination of two things. In the else clause you have this:

Session["p_skok"] = Session["z_skok"];

Once you do that, those two variables refer to the same list. Now whatever you do to one list, you're doing to the other, because they're the same list.

Then you're setting Session["iteracja"] = 1;, which means next time the condition if (Session["iteracja"] != null) will be true.

Within that condition you're making changes to lista_odnosnik_skok, which is Session["p_skok"] which is the same list as Session["z_skok"];.


To solve it, don't set the one session variable equal to the other. You could do this:

var existingList = (List<int>)Session["z_skok"];
Session["p_skok"] = new List<int>(existingList);

Now you've created a new list that contains the same elements as the original list. They're two distinct lists, so modifying one doesn't modify the other.

It's worth noting that this works because int is a value type, not a reference type, so when you add the values from one list to the other list you're creating new values. You can modify the values in one list without modifying the others.

If the items in the list were reference types you'd still have a similar problem. You'd have two lists (good) but they would both contain references to the same objects (probably bad). You'd be able to add or delete on one list without modifying the other list, but modifying the item in the list would modify the item in the other list, because they're both the same item.

But again, that's just for explanation. The list contains int so in this case it's not a problem.


It might also be easier to follow if you read everything you need out of Session into variables at the beginning, and then save everything back to Session at the end. That way you're not trying to keep track of both local variables and session variables at the same time. It's confusing, which means it's easier to make mistakes.

You might even find it helpful to define a new class that contains all of these lists. Retrieve that one object from session (if it's null create new one), and when you're done working with it, save the whole object. It's the same as what you're doing, but now you're only dealing with one session variable instead of five, and it's even easier to keep track of.

Upvotes: 2

Caius Jard
Caius Jard

Reputation: 74605

At some point in the lifecycle of your program you set these two session variables equivalent:

Session["p_skok"] = Session["z_skok"];

This line of code is in the else block. The session will survive for a long time, perhaps hours:


enter image description here


After this line of code has run they will both refer to the same list object in memory and any changes inflicted on the contents of either Session["p_skok"] or lista_odnosnik_skok, or Session["z_skok"]; or lista_odnosnik_skok_pomocnicza will all have the same effect because they're all references to the same List<int>

Upvotes: 2

Related Questions