1

我在从 InProc 会话状态中检索会话变量的多个实例时遇到问题。

在下面的代码中,我将一个简单的 BusinessObject 持久化到 Page_Load 事件的会话变量中。单击按钮后,我尝试将对象检索回同一 BusinessObject 的 2 个新声明的实例中。

一切都很好,直到我在第一个实例中更改了一个属性,它也更改了第二个实例。

这是正常行为吗?我会认为这些是新实例,它们不会表现出静态行为?

有什么想法我哪里出错了吗?

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        If Not Page.IsPostBack Then
            ' create a new instance of a business object and set a containg variable
            Dim BO As New BusinessObject
            BO.SomeVariable = "test"
            ' persist to inproc session
            Session("BO") = BO
        End If

    End Sub

    Protected Sub btnRetrieveSessionVariable_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnRetrieveSessionVariable.Click

        ' retrieve the session variable to a new instance of BusinessObject
        Dim BO1 As New BusinessObject
        If Not Session("BO") Is Nothing Then BO1 = Session("BO")

        ' retrieve the session variable to a new instance of BusinessObject
        Dim BO2 As New BusinessObject
        If Not Session("BO") Is Nothing Then BO2 = Session("BO")

        ' change the property value on the first instance
        BO1.SomeVariable = "test2"

        ' why has this changed on both instances?
        Dim strBO1Property As String = BO1.SomeVariable
        Dim strBO2Property As String = BO2.SomeVariable

    End Sub

    ' simple BusinessObject class
    Public Class BusinessObject
        Private _SomeVariable As String

        Public Property SomeVariable() As String
            Get
                Return _SomeVariable
            End Get
            Set(ByVal value As String)
                _SomeVariable = value
            End Set
        End Property
    End Class
4

2 回答 2

0

您正在实例化两个新对象,然后将它们中的每一个设置为同一个对象(即来自会话的对象),因此您的行为完全符合您的预期。

顺便说一句,您可能希望考虑如果用户在一个选项卡中打开其中两个页面,您的页面将如何执行 - 您的业务对象在会话中是否会给您带来一些问题?

于 2010-03-16T12:42:27.773 回答
0

你的 BO1 和 BO2 是同一个对象 BO1 是一个引用内存中某个区域的名称;BO2 是引用相同内存区域的另一个名称;Session("BO") 引用相同的内存区域。

要真正创建不同的对象 BO1 和 BO2,您应该创建对象的副本 - 例如在业务对象类中实现 Clone() 方法。

于 2010-03-16T12:43:04.713 回答