是时候学习一些基础知识了。
查看下面的代码:
protected void Button1_Click(object sender, EventArgs e)
{
List<string> a;
if(Session["data"] == null)
{
a = new List<string>();
a.Add("abc");
a.Add("def");
a.Add("ghi");
Session["data"] = a;
}
else
{
a = (Session["data"] as List<string>);
}
a.Add("jkl");
foreach (string s in a)
{
lblTest.Text += s + "<br />";
}
}
代码隐藏中没有其他地方可以我对会话执行任何操作。此代码的预期行为是在第一次运行(单击)会话中将保留对"a"的引用。但是"a"在上述函数中具有本地范围,因此必须在某处将"a"的值复制到会话中。这是在哪里发生的?它是否在函数执行之前发生,因为发生的任何其他事情(即页面卸载、验证、渲染)列表"a"将不可用。那么,分配或引用的值何时何地存储在会话中呢?
那么,分配或引用的值何时何地存储在会话中呢?
这里:
Session["data"] = a;
在第二次运行中,您将从会话中检索 并向其中添加一个元素。但是由于List<string>
是引用类型,因此a
和Session["data"]
现在都指向内存中的同一位置,因此当您向a
添加元素时,您基本上是在修改Session["data"]
因此您无需再次调用Session["data"] = a
。
a
是对List<string>
实例的引用。当您分配Session["data"] = a
时,它现在也具有对同一 List<string>
实例的引用。因此,尽管a
超出了范围,但该列表实例仍然存在,因为至少保留了一个引用。访问Session["data"]
将继续返回对该实例的引用,直到将其从会话中删除(或替换为其他内容)。