Properties, Constructors and Shared Members

18.1 Property Types

Public Class Person
    ' Auto-implemented property with a default value
    Public Property Name As String = "Unknown"

    ' Read-only auto-property (assignable in the constructor)
    Public ReadOnly Property Id As Guid = Guid.NewGuid()

    ' Full property with validation
    Private _age As Integer
    Public Property Age As Integer
        Get
            Return _age
        End Get
        Set(value As Integer)
            If value < 0 OrElse value > 150 Then
                Throw New ArgumentOutOfRangeException(NameOf(value))
            End If
            _age = value
        End Set
    End Property

    ' Computed read-only property
    Public ReadOnly Property IsAdult As Boolean
        Get
            Return Age >= 18
        End Get
    End Property

    ' Different access levels for Get and Set
    Public Property Email As String
        Get
            Return _email
        End Get
        Private Set(value As String)
            _email = value
        End Set
    End Property
    Private _email As String

    ' Write-only property (rare)
    Public WriteOnly Property Password As String
        Set(value As String)
            _hash = Hash(value)
        End Set
   
…

18.2 Constructors

If you define any constructor, the implicit parameterless one disappears unless you declare it.

Private constructors prevent external instantiation (singletons, factory methods).

Public Class Product
    Public Property Name As String
    Public Property Price As Decimal

    Public Sub New()                                 ' parameterless constructor
        Me.New("Unnamed", 0)                         ' constructor chaining (must be the first statement)
    End Sub

    Public Sub New(name As String, price As Decimal)
        Me.Name = name
        Me.Price = price
    End Sub

    Shared Sub New()                                 ' shared (static) constructor: runs once
        Console.WriteLine("Product type initialized")
    End Sub
End Class

18.3 Shared Members

Public Class Counter
    Private Shared _instances As Integer = 0
    Public Shared ReadOnly Property Instances As Integer
        Get
            Return _instances
        End Get
    End Property

    Public Sub New()
        _instances += 1
    End Sub

    Public Shared Function Create() As Counter     ' factory method
        Return New Counter()
    End Function
End Class

Dim c1 = Counter.Create()
Dim c2 As New Counter()
Console.WriteLine(Counter.Instances)               ' 2

18.4 Singleton Pattern

Public NotInheritable Class AppConfig
    Private Shared ReadOnly _instance As New Lazy(Of AppConfig)(Function() New AppConfig())
    Public Shared ReadOnly Property Instance As AppConfig
        Get
            Return _instance.Value
        End Get
    End Property
    Private Sub New()
    End Sub
    Public Property ConnectionString As String
End Class

18.5 Init-Only Properties

VB 16.9 can consume C# init accessors (set them in object initializers) but can't declare them.