Structures, Enums, Tuples and Value Semantics
12.1 Structures
Guidelines: keep structures small and immutable (avoid mutable structs: copies cause surprises). Implement IEquatable(Of T) to avoid boxing.
Public Structure Money
Implements IEquatable(Of Money), IComparable(Of Money)
Public ReadOnly Property Amount As Decimal
Public ReadOnly Property Currency As String
Public Sub New(amount As Decimal, currency As String)
Me.Amount = amount
Me.Currency = currency
End Sub
Public Shared Operator +(a As Money, b As Money) As Money
EnsureSame(a, b)
Return New Money(a.Amount + b.Amount, a.Currency)
End Operator
Public Shared Operator =(a As Money, b As Money) As Boolean
Return a.Equals(b)
End Operator
Public Shared Operator <>(a As Money, b As Money) As Boolean
Return Not a.Equals(b)
End Operator
Public Shared Narrowing Operator CType(m As Money) As Decimal
Return m.Amount
End Operator
Private Shared Sub EnsureSame(a As Money, b As Money)
If a.Currency <> b.Currency Then Throw New InvalidOperationException("Currency mismatch")
End Sub
Public Overloads Function Equals(other As Money) As Boolean Implements IEquatable(Of Money).Equals
Return Amount = other.Amount AndAlso Currency = other.Currency
End Function
Public Overrides Function Equals(obj
…12.2 Enums and Flags
<Flags>
Public Enum FileAccessRights As Integer
None = 0
Read = 1 << 0
Write = 1 << 1
Delete = 1 << 2
Full = Read Or Write Or Delete
End Enum
Dim rights = FileAccessRights.Read Or FileAccessRights.Write
If rights.HasFlag(FileAccessRights.Write) Then Console.WriteLine("can write")
Dim names = [Enum].GetNames(GetType(FileAccessRights))
Dim parsed = [Enum].Parse(Of FileAccessRights)("Read, Write")12.3 Tuples and Anonymous Types
VB has no tuple deconstruction. Access the elements by name. Anonymous types can't leave a method in a typed way.
Function Range(values As IEnumerable(Of Integer)) As (Min As Integer, Max As Integer)
Return (values.Min(), values.Max())
End Function
Dim r = Range({4, 9, 1})
Console.WriteLine($"{r.Min}..{r.Max}")
Dim summary = New With {Key .Region = "West", .Total = 1200D} ' anonymous type (Key = used in equality)12.4 Records from C#
VB can consume C# record types (properties, equality, and init setters in object initializers in VB 16.9), but can't declare records or use With expressions. In VB, write immutable classes with ReadOnly properties plus equality members.