我有一个奇怪的问题。我的变量之一通过此函数更改(下面的代码)。我不知道怎么可能。我想更改Session["p_skok"]
,但是在某种程度上,变量Session["z_skok"]
也正在更改。
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();
}
}
我进行了一些调试,发现减少的原因是代码的lista_odnosnik_skok[i]--;
部分。你知道会发生什么吗?
答案 0 :(得分:2)
在程序生命周期的某个时刻,您将这两个会话变量设置为等效:
Session["p_skok"] = Session["z_skok"];
此行代码位于else
块中。该会话将持续很长时间,甚至可能长达几个小时:
这行代码运行之后,它们都将引用内存中的同一列表对象,并且对Session["p_skok"]
或lista_odnosnik_skok
或Session["z_skok"];
或{ {1}}都将具有相同的效果,因为它们都是对同一lista_odnosnik_skok_pomocnicza
答案 1 :(得分:2)
这是两件事的结合。在else
子句中,您可以这样:
Session["p_skok"] = Session["z_skok"];
一旦执行此操作,这两个变量将引用同一列表。现在,无论您对一个列表执行什么操作,您都对另一个列表执行操作,因为它们是相同的列表。
然后您要设置Session["iteracja"] = 1;
,这意味着下一次条件if (Session["iteracja"] != null)
将为真。
在这种情况下,您将更改lista_odnosnik_skok
,即Session["p_skok"]
,它与Session["z_skok"];
相同。
要解决此问题,请不要将一个会话变量设置为等于另一个。您可以这样做:
var existingList = (List<int>)Session["z_skok"];
Session["p_skok"] = new List<int>(existingList);
现在,您已经创建了一个新列表,其中包含与原始列表相同的元素。它们是两个不同的列表,因此修改一个列表不会修改另一个列表。
值得注意的是,这是有效的,因为int
是一种值类型,而不是引用类型,因此,当您将一个列表中的值添加到另一个列表中时,便会创建新值。您可以修改一个列表中的值,而无需修改其他列表。
如果列表中的项目是引用类型,您仍然会遇到类似的问题。您将有两个列表(好),但它们都将包含对相同对象的引用(可能不好)。您可以在一个列表上添加或删除,而无需修改其他列表,但是修改列表中的项目将修改另一个列表中的项目,因为它们都是同一项目。
但是,这仅是一个解释。该列表包含int
,因此在这种情况下这不是问题。
如果您从Session
开始将所需的所有内容读入变量,然后将所有内容保存回Session
,则可能更容易理解。这样,您就不会试图同时跟踪局部变量和会话变量。令人困惑,这意味着更容易犯错误。
您甚至可能会发现定义一个包含所有这些列表的新类很有帮助。从会话中检索一个对象(如果为空,则创建一个新对象),并在完成使用后保存整个对象。与您的操作相同,但是现在您只需要处理一个会话变量,而不是五个,并且更容易进行跟踪。