Apologies for the appalling title.
I have mocked up this code to mimic an issue I was encountering on a project.
I want to know why the property status does not 'stick'. Stepping through the code I can even see it setting the property!
Is it something to do with Structure being a value type?
Here is the code, it is standalone.
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
When I run clsTest.test
I get the following output-
clsTest.test
Initialised Status : 0
Initialised Original Status : 5
Next Status : 0
Next Original Status : 5
...even though setStatusToTen
is doing exactly what it says on the tin!
This is yet another case of mutable structs being evil. Avoid using structures for this purpose. As a reference:
Why are mutable structs “evil”?
Yes, its because Structures are value types. When a struct object is assigned to another struct object, the full content of the struct is copied and duplicated. (See this C# example)
So in your code, this set:
Set(ByVal value As info)
_heldInfo = value
End Set
... effectively results in two copies of the structure being made. One is internal to holder
and is represented by _heldInfo
, and the other is 'external' to holder
, and is represented by myHolder.info
. After the copy has been made, when you set values on one of them, the other is not affected.
If you add this method to holder
:
Public Sub printStatus()
Debug.Print("Internal Status : {0}", _heldInfo.status)
End Sub
... you will find where your value of 10
went.
精彩评论