Generics

23.1 Generic Methods

Function Max(Of T As IComparable(Of T))(a As T, b As T) As T
    Return If(a.CompareTo(b) > 0, a, b)
End Function

Sub Swap(Of T)(ByRef a As T, ByRef b As T)
    Dim tmp = a : a = b : b = tmp
End Sub

Console.WriteLine(Max(3, 7))
Console.WriteLine(Max("apple", "banana"))
Console.WriteLine(Max(Of Double)(1.5, 2.5))       ' explicit type argument

23.2 Generic Classes

Public Class Repository(Of T As {Class, IEntity, New})
    Private ReadOnly _items As New List(Of T)

    Public Sub Add(item As T)
        _items.Add(item)
    End Sub

    Public Function GetById(id As Integer) As T
        Return _items.FirstOrDefault(Function(x) x.Id = id)
    End Function

    Public Function CreateNew() As T
        Return New T()                          ' allowed by the New constraint
    End Function

    Public ReadOnly Property Count As Integer
        Get
            Return _items.Count
        End Get
    End Property
End Class

Public Interface IEntity
    Property Id As Integer
End Interface

Public Class Customer
    Implements IEntity
    Public Property Id As Integer Implements IEntity.Id
    Public Property Name As String
End Class

Dim repo As New Repository(Of Customer)()
repo.Add(New Customer With {.Id = 1, .Name = "Ana"})

23.3 Constraints

As Structure Value type (non-nullable) Has a public parameterless constructor As SomeBaseClass Inherits from the base class As ISomeInterface Implements the interface

Must be or derive from another type parameter As {Class, IEntity, New}

23.4 Generic Interfaces, Delegates and Variance

Public Interface IProducer(Of Out T)            ' covariant: IProducer(Of String) → IProducer(Of Object)
    Function Produce() As T
End Interface
Public Interface IConsumer(Of In T)             ' contravariant
    Sub Consume(item As T)
End Interface
Public Delegate Function Transformer(Of In TIn, Out TOut)(input As TIn) As TOut

Dim strings As IEnumerable(Of String) = {"a", "b"}
Dim objects As IEnumerable(Of Object) = strings  ' covariance works with IEnumerable(Of Out T)