我正在使用 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/
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife
我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2
我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog
我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案
对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs