2010-03-31 54 views
3

我有一个asp:ImageButton与OnClick =“Btn_OnClick”。
在Btn_OnClick我有这样一行:C# - 使用会话存储变量的副本而不是引用

DataTable dtTable = (DataTable)Session["someSessionKey"] 

和dtTable在功能改变。

我注意到,如果按钮的点击次数超过一次,我从会话中获取的dtTable将包含更改后的表,这可能意味着dtTable不是副本,而是会话变量的引用。

如何更改Session [“someSessionKey”]的副本,而不是实际值?
谢谢!

回答

5
DataTable dtTable = ((DataTable)Session["someSessionKey"]).Copy(); 
+0

问题在于,dtTable在Clone()后没有包含任何内容。只是一张空桌子。如果我不克隆它,没关系。 – Nir 2010-03-31 08:45:43

+0

Oups,对不起。答案现在已更正。 – svinto 2010-03-31 08:52:10

+0

非常感谢! :-) – Nir 2010-03-31 09:28:05

2

如果在Session对象实现ICloneable,您可以使用var myCopy = mySessionObject.Clone();。然后您必须阅读该对象的文档才能看到它的确切含义。

这是因为没有克隆的通用解决方案。大多数情况下,对象具有其他非标量对象作为属性,所以如果您需要克隆这些子对象,它总是取决于场景。

当您创作自己的课程时,您始终可以调用System.Object中定义的受保护的MemberwiseClone()方法来获得平面克隆。然后,您可以选择是否要添加一些额外的克隆逻辑,以及是否希望将其用于外部呼叫者。

如果会话中的对象是List<T>IEnumerable<T>,则可以执行var myCopiedList = new List<T>(myListInSession);。请记住,该列表中的单个对象是在该情况下克隆的而不是。您必须通过它们foreach并手动克隆每个对象。它与DataTable类似。您可能需要手动创建新实例并复制内容。

要手动克隆不支持任何公共方法的对象,您必须创建一个新实例。然后,您将手动将原始对象的每个属性分配给克隆的对象。这不仅是单调乏味,常常也不起作用,因为有受保护的成员,您无法轻松访问。

最后,您可以使用反射或其他技巧来尝试克隆对象。快速谷歌搜索给了我这个结果:C# Object clone wars