我有一个asp:ImageButton,OnClick =“Btn_OnClick” 在Btn_OnClick中我有这一行:
DataTable dtTable = (DataTable)Session["someSessionKey"]
和dtTable在函数中被更改。
我注意到如果按钮被多次点击,我从会话中获取的dtTable包含更改的表,可能意味着dtTable不是副本而是会话变量的引用。
如何更改Session [“someSessionKey”]的副本,而不是实际值?
谢谢!
答案 0 :(得分:5)
DataTable dtTable = ((DataTable)Session["someSessionKey"]).Copy();
答案 1 :(得分:2)
如果会话中的对象实现ICloneable
,您可以使用var myCopy = mySessionObject.Clone();
。然后,您必须阅读该对象的文档,以了解它究竟是做什么的。
这是因为克隆没有通用的解决方案。大多数情况下,对象将其他非标量对象作为属性,因此如果您还需要克隆这些子对象,它总是取决于场景。
当您创建自己的类时,您始终可以调用MemberwiseClone()
中定义的受保护System.Object
方法来获取平面克隆。然后,您可以选择是否要添加一些其他克隆逻辑,以及是否要将其用于外部呼叫者。
如果会话中的对象是List<T>
或IEnumerable<T>
,您可以执行var myCopiedList = new List<T>(myListInSession);
。请记住,在这种情况下,该列表中的各个对象不克隆。您必须foreach
通过它们并手动克隆每个对象。它与DataTable
类似。您可能需要手动创建新实例并复制内容。
要手动克隆不支持任何公共方法的对象,您必须创建它的新实例。然后,您将手动将原始对象中的每个属性分配给克隆对象。这可能不仅乏味,通常它也不会起作用,因为有受保护的成员,你无法轻易访问。
最后,您可以使用反射或其他技巧来尝试克隆对象。快速谷歌搜索给了我结果:C# Object clone wars。