是否隐式调用.Net属性设置器?

Aur*_*eer 10 .net c# asp.net session properties

我正在使用C#编写ASP.Net 2.0项目.我有一些数据存储在会话状态.为了便于使用,它包含在属性中,如下所示:

protected IList<Stuff> RelevantSessionData
{
    get
    {
        return (IList<Stuff>) Session["relevant_key"];
    }
    set
    {
        Session["relevant_key"] = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

获取和设置值完全符合您的预期.如果我想清除该值,我只需将其设置为null,并且没有问题.但是,在另一个开发人员的页面中,他调用了集合的Clear()方法.我认为这将是一个错误,但它似乎工作,我不明白为什么.它的工作原理如下:

Debug.WriteLine(RelevantSessionData.Count);    //outputs, say, 3
RelevantSessionData.Clear();
Debug.WriteLine(RelevantSessionData.Count);    //outputs 0
Run Code Online (Sandbox Code Playgroud)

为什么这样做?我天真的期望是中间行从会话加载序列化值,反序列化为对象,调用Clear()该对象,然后让未命名对象超出范围.这将是一个错误,因为存储在Session中的值将保持不变.但显然,它足够聪明,可以调用属性setter并将新更改的集合序列化回会话.

这让我有点紧张,因为我们的遗留代码中有些地方属性设置器有副作用,我不希望那些被调用,如果不是这样的话.

在这种情况下,属性setter是否总是被调用?还有别的事吗?或者我是否完全误解了这里发生的事情?

[补充解释答案]
事实证明误解了.我知道存储在Session中的对象必须是可序列化的,并且基于此我对集合在内部的行为做了太多假设.我是在思索.

存储对象(my IList)只有一个实例.每次调用getter都会返回对同一实例的引用.所以上面引用的代码就像看起来一样,不需要特殊的魔法.

并回答标题问题:不,不会暗中调用setter.

Tim*_*dge 4

是的,你是对的,如果你的 setter/getter 正在序列化/反序列化对象,这将是一个错误。但这种情况并非如此。相反,您是根据参考通过的。

所以基本上发生的事情是,示例中的第一行通过 get 获取项目,并基于此调用 Count。然后第二行出去并再次调用 get,返回相同的对象,运行清除,然后第三行执行与第一行相同的操作。

如果你像这样编写你的 setter/getter ,你就会有一个“bug”

protected IList<Stuff> RelevantSessionData
{
    get
    {
        return (IList<Stuff>) JSON.ConvertFromString(Session["relevant_key"]);
    }
    set
    {
        Session["relevant_key"] = JSON.ConvertToString(value);
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,每次调用 get 块都会创建一个新对象。但由于上面的示例只是传递对同一对象的引用,因此您不会看到这个“错误”。

我说“bug”是因为它并不是真正的bug,它只是对幕后发生的事情的误解。

我希望这有帮助。