gpt4 book ai didi

c# - .Net 属性 setter 是否曾被隐式调用?

转载 作者:可可西里 更新时间:2023-11-01 09:13:57 26 4
gpt4 key购买 nike

我正在使用 C# 进行 ASP.Net 2.0 项目。我有一些数据存储在 session 状态中。为了便于使用,它被包装在一个属性中,如下所示:

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

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

这让我有点紧张,因为在我们的遗留代码中有一些地方的属性 setter 有副作用,我不希望这些 setter 在无意的情况下被调用。

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

[添加解释答案]
原来是误会了。我知道存储在 Session 中的对象必须是可序列化的,基于此我对集合的内部行为方式做了太多假设。我想多了。

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

然后回答标题问题:不,不会隐式调用 setter。

最佳答案

是的,您是对的,如果您的 setter/getter 正在序列化/反序列化对象,这将是一个错误。但这种情况并非如此。相反,您是根据引用传递的。

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

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

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

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

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

希望对您有所帮助。

关于c# - .Net 属性 setter 是否曾被隐式调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2141060/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com