The place for the VB community to join our collective voice! See https://github.com/CommunityVB/Main for more info.
readonly Point _point;
_point
Public Structure Point
Public Sub New (x As Integer, y As Integer)
Me.X = x
Me.Y = y
End Sub
Public ReadOnly Property X As Integer
Public ReadOnly Property Y As Integer
Public Overrides Function ToString() As String
Return $"{X}, {Y}"
End Function
End Structure
To my knowledge the above is a "safe" Structure
; where the only "annoyance" would be in the fact that I have to create a New
where it would be nice if the With
functionality could initialize ReadOnly
properties (I haven't attempted this lately, so don't know if it has changed recently to be allowed).
There are also attributes that provide additional hints (StructLayout
) to the compiler (and have been for ages) as to how to handle this structure (in the context of interop - I'm not sure they do anything outside of that scenario). To my knowledge this would be "pinnable" since it's only using blittable types (I could be wrong on this, but assuming...), so an array of this could be created outside of the main GC. (I haven't needed this scenario and the documentation seems a bit confusing on this subject - at least to me.)
As for passing something like this by reference, that seems like trying to (at least to me) force something that (could potentially) be a value type, thus passable on the stack, into something that should be a reference type. And we already have this... if you want by reference, wouldn't that be a Class
?
Class
<> Structure
They serve two very different purposes and, although they appear to have similar functionality/purpose... they simply don't and we shouldn't try to force them to be "the same".
And it is a good point to treat structs in interpolated strings with caution if some parts of the interpolated string do some changes in the struct.
Structure CoordsStruct
Public Shared ToStringCount As Integer = 0
Public Sub New(x As Double, y As Double)
Me.X = x
Me.Y = y
End Sub
Public Property X As Double
Public Property Y As Double
Public Overrides Function ToString() As String
ToStringCount += 1
X += 1
Return $"({X}, {Y}, {ToStringCount})"
End Function
End Structure
Class CoordsCls
Public Shared ToStringCount As Integer = 0
Public Sub New(x As Double, y As Double)
Me.X = x
Me.Y = y
End Sub
Public Property X As Double
Public Property Y As Double
Public Overrides Function ToString() As String
ToStringCount += 1
X += 1
Return $"({X}, {Y}, {ToStringCount})"
End Function
End Class
Function Foo(ByRef oo As CoordsStruct) As String
Return $"{oo} {oo}"
End Function
Function Foo(oo As CoordsCls) As String
Return $"{oo} {oo}"
End Function
Sub Main()
Dim cs As New CoordsStruct(3, 5)
Dim cs_s1 As String = $"{cs} {cs} {Foo(cs)}"
Dim cs_s2 As String = $"{cs} {cs} {Foo(cs)}"
Dim cs_s3 As String = $"{cs} {cs} {Foo(cs)}"
Dim cc As New CoordsCls(3, 5)
Dim cc_s1 As String = $"{cc} {cc} {Foo(cc)}"
Dim cc_s2 As String = $"{cc} {cc} {Foo(cc)}"
Dim cc_s3 As String = $"{cc} {cc} {Foo(cc)}"
Stop
End Sub
Dim cs_s1 As String = $"{cs} {cs} {Foo(cs)}"
gives different results thanDim cs_s1 As String = cs & " " & cs & " " & Foo(cs)
And it is a good point to treat structs in interpolated strings with caution
var v = myStruct.Mutate();
{}
or outside. nothing changes with that. teh method is called first, and the result value is what is passed into the interpolation.
that's true inside {}
or outside. nothing changes with that. teh method is called first, and the result value is what is passed into the interpolation.