C# - 使用Session存储变量的副本而不是引用

时间:2010-03-31 07:59:36

标签: c#

我有一个asp:ImageButton,OnClick =“Btn_OnClick” 在Btn_OnClick中我有这一行:

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

和dtTable在函数中被更改。

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

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

2 个答案:

答案 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