【发布时间】:2011-01-09 14:36:54
【问题描述】:
我正在使用 C# 编写一个 ASP.Net 2.0 项目。我有一些数据存储在会话状态中。为了方便使用,它被包裹在一个属性中,像这样:
protected IList<Stuff> RelevantSessionData
{
get
{
return (IList<Stuff>) Session["relevant_key"];
}
set
{
Session["relevant_key"] = value;
}
}
获取和设置值的工作方式完全符合您的预期。如果我想清除该值,我只是将它设置为null,并且没有问题。但是,在另一个开发人员的页面中,他调用了集合的 Clear() 方法。我认为这将是一个错误,但它似乎工作,我不明白为什么。它是这样工作的:
Debug.WriteLine(RelevantSessionData.Count); //outputs, say, 3
RelevantSessionData.Clear();
Debug.WriteLine(RelevantSessionData.Count); //outputs 0
为什么会这样?我天真的期望是中间行从会话加载序列化值,反序列化为一个对象,在该对象上调用Clear(),然后让未命名的对象超出范围。那将是一个错误,因为存储在 Session 中的值将保持不变。但显然,调用属性设置器并将新更改的集合序列化回会话中已经足够聪明了。
这让我有点紧张,因为在我们的遗留代码中有些地方属性设置器有副作用,如果不是有意的,我不希望它们被调用。
在这种情况下是否总是调用属性设置器?有其他事情发生吗?还是我完全误解了这里发生的事情?
[添加解释答案]
原来是误会了。我知道存储在 Session 中的对象必须是可序列化的,并且基于此我对集合内部的行为做了太多假设。我想多了。
存储对象只有一个实例(我的IList)。对 getter 的每次调用都会返回对同一实例的引用。所以上面引用的代码就像它看起来一样工作,不需要特殊的魔法。
并回答标题问题:不,setter 不会被隐式调用。
【问题讨论】:
标签: c# .net asp.net session properties