这是某种引用问题吗?价值不坚持

时间:2010-09-27 23:25:06

标签: vb.net class structure value-type

为令人震惊的头衔道歉。

我已经模拟了这段代码,以模仿我在项目中遇到的问题。

我想知道为什么属性状态不会“粘住”。单步执行代码,我甚至可以看到它设置属性!

与Structure是值类型有关吗?

这是代码,它是独立的。

Imports System.Diagnostics

Public Class clsTest
    Public Shared Sub test()
        Dim myHolder As New holder

        myHolder.info = New info(5)
        With myHolder.info
            Debug.Print("Initialised Status : {0}", .status)
            Debug.Print("Initialised Original Status : {0}", .originalStatus)
            myHolder.setStatusToTen()
            Debug.Print("Next Status : {0}", .status)
            Debug.Print("Next Original Status : {0}", .originalStatus)
        End With
    End Sub
End Class

Public Class holder
    Private _heldInfo As info

    Public Property info() As info
        Get
            Return _heldInfo
        End Get
        Set(ByVal value As info)
            _heldInfo = value
        End Set
    End Property

    Public Sub setStatusToTen()
        _heldInfo.status = 10
    End Sub
End Class

Public Structure info
    Private _iOriginalStatus, _iStatus As Integer

    Public Sub New(ByVal iStartingStatus As Integer)
        _iOriginalStatus = iStartingStatus
    End Sub

    Public ReadOnly Property originalStatus() As Integer
        Get
            Return _iOriginalStatus
        End Get
    End Property

    Public Property status() As Integer
        Get
            Return _iStatus
        End Get
        Set(ByVal value As Integer)
            _iStatus = value
        End Set
    End Property
End Structure

当我运行clsTest.test时,我得到以下输出 -

clsTest.test
Initialised Status : 0
Initialised Original Status : 5
Next Status : 0
Next Original Status : 5

......即使setStatusToTen完全按照它在锡上所说的那样做了!

2 个答案:

答案 0 :(得分:2)

这是另一个可变结构是邪恶的案例。避免为此目的使用结构。作为参考:

Why are mutable structs “evil”?

答案 1 :(得分:1)

是的,因为Structures是值类型。将struct对象分配给另一个struct对象时,将复制和复制该struct的完整内容。 (See this C# example

所以在你的代码中,这个集合:

Set(ByVal value As info)
        _heldInfo = value
End Set

...有效地产生了两个正在制作的结构副本。一个是holder的内部,由_heldInfo表示,另一个是holder的“外部”,由myHolder.info表示。复制完成后,当您在其中一个上设置值时,另一个不受影响。

如果您将此方法添加到holder

Public Sub printStatus()
    Debug.Print("Internal Status : {0}", _heldInfo.status)
End Sub

...您会找到10的值。