Claude
Skills
Sign in
Back

vb-core

Included with Lifetime
$97 forever

Core VB.NET patterns, type safety, modern language features

toolchainvisualbasicvb.netdotnettype-safety

What this skill does


# Visual Basic .NET Core Patterns

Modern VB.NET (2019+) best practices with focus on type safety, LINQ, async/await, and .NET integration.

## Quick Start

```vb
' Always enable strict type checking
Option Strict On
Option Explicit On
Option Infer On

' Modern class definition
Public Class Customer
    Public Property Id As Integer
    Public Property Name As String
    Public Property Email As String

    ' Constructor
    Public Sub New(id As Integer, name As String, email As String)
        Me.Id = id
        Me.Name = name
        Me.Email = email
    End Sub
End Class

' Modern async method
Public Async Function GetCustomerAsync(id As Integer) As Task(Of Customer)
    Dim result = Await database.QueryAsync(Of Customer)(
        "SELECT * FROM Customers WHERE Id = @id",
        New With {.id = id}
    )
    Return result.FirstOrDefault()
End Function

' LINQ query
Dim activeCustomers = From c In customers
                      Where c.IsActive AndAlso c.Balance > 0
                      Order By c.Name
                      Select c
```

## Type Safety (Critical)

### Option Strict On

```vb
' ALWAYS at top of every file
Option Strict On
Option Explicit On
Option Infer On

' Why:
' - Option Strict: Prevents implicit narrowing conversions
' - Option Explicit: Requires variable declaration
' - Option Infer: Enables type inference (but still type-safe)
```

### Explicit Types vs Inference

```vb
' ✅ Good: Explicit when clarity helps
Dim customerName As String = GetCustomerName(id)
Dim count As Integer = GetCount()

' ✅ Good: Inference when type is obvious
Dim customer = New Customer(1, "John", "[email protected]")
Dim items = New List(Of String) From {"a", "b", "c"}

' ❌ Bad: Dim without type and no inference
Dim data = GetData()  ' What type is data?

' ✅ Better: Be explicit
Dim data As DataTable = GetData()
```

### Nullable Types

```vb
' Modern nullable syntax (VB 15.5+)
Dim middleName As String? = Nothing
Dim age As Integer? = Nothing

' Null-conditional operator
Dim length As Integer? = middleName?.Length

' Null-coalescing operator
Dim displayName As String = middleName If Nothing

' Check for null
If age IsNot Nothing Then
    Console.WriteLine($"Age: {age.Value}")
End If

' GetValueOrDefault
Dim years As Integer = age.GetValueOrDefault(0)
```

## Modern Language Features

### String Interpolation

```vb
' ✅ Modern (VB 14+)
Dim message = $"Customer {customer.Name} has balance {customer.Balance:C}"

' ❌ Old style (avoid)
Dim message = String.Format("Customer {0} has balance {1:C}", customer.Name, customer.Balance)

' ❌ Concatenation (avoid for complex strings)
Dim message = "Customer " & customer.Name & " has balance " & customer.Balance.ToString("C")
```

### Lambda Expressions

```vb
' Single-line lambda
Dim isAdult = Function(age As Integer) age >= 18

' Multi-line lambda
Dim calculateTax = Function(amount As Decimal) As Decimal
                       Dim rate = If(amount > 10000, 0.2D, 0.15D)
                       Return amount * rate
                   End Function

' Lambda in LINQ
Dim adults = customers.Where(Function(c) c.Age >= 18).ToList()

' Action lambda (Sub)
items.ForEach(Sub(item) Console.WriteLine(item))
```

### Collection Initializers

```vb
' List initialization
Dim numbers = New List(Of Integer) From {1, 2, 3, 4, 5}

' Dictionary initialization
Dim config = New Dictionary(Of String, String) From {
    {"ConnectionString", "Server=..."},
    {"Timeout", "30"},
    {"MaxRetries", "3"}
}

' Array initialization
Dim names As String() = {"Alice", "Bob", "Charlie"}
```

### Tuple Support

```vb
' Named tuples (VB 15.3+)
Function GetCustomerInfo(id As Integer) As (Name As String, Email As String)
    Return ("John Doe", "[email protected]")
End Function

' Usage
Dim info = GetCustomerInfo(1)
Console.WriteLine($"{info.Name}: {info.Email}")

' Deconstruction
Dim (customerName, customerEmail) = GetCustomerInfo(1)
```

## LINQ Patterns

### Query Syntax vs Method Syntax

```vb
' Query syntax (more readable for complex queries)
Dim query = From c In customers
            Where c.IsActive
            Order By c.Name
            Select New With {
                .Name = c.Name,
                .Email = c.Email
            }

' Method syntax (more flexible)
Dim query = customers _
    .Where(Function(c) c.IsActive) _
    .OrderBy(Function(c) c.Name) _
    .Select(Function(c) New With {
        .Name = c.Name,
        .Email = c.Email
    })
```

### Common LINQ Operations

```vb
' Filtering
Dim activeCustomers = customers.Where(Function(c) c.IsActive).ToList()

' Projection
Dim names = customers.Select(Function(c) c.Name).ToList()

' Ordering
Dim sorted = customers.OrderBy(Function(c) c.Name).ThenBy(Function(c) c.Id)

' Grouping
Dim grouped = From c In customers
              Group c By c.City Into Group
              Select City, Customers = Group

' Aggregation
Dim total = orders.Sum(Function(o) o.Amount)
Dim average = orders.Average(Function(o) o.Amount)
Dim count = customers.Count(Function(c) c.IsActive)

' First/Single
Dim first = customers.FirstOrDefault(Function(c) c.Id = 1)
Dim single = customers.SingleOrDefault(Function(c) c.Email = email)

' Any/All
Dim hasActive = customers.Any(Function(c) c.IsActive)
Dim allActive = customers.All(Function(c) c.IsActive)
```

## Async/Await Patterns

### Async Method Declaration

```vb
' Return Task(Of T) for async methods with return value
Public Async Function GetDataAsync() As Task(Of String)
    Dim result = Await httpClient.GetStringAsync(url)
    Return result
End Function

' Return Task for async methods without return value
Public Async Function SaveDataAsync(data As String) As Task
    Await File.WriteAllTextAsync(filePath, data)
End Function

' Async Sub only for event handlers
Private Async Sub Button_Click(sender As Object, e As EventArgs) Handles Button.Click
    Await ProcessDataAsync()
End Sub
```

### Async Best Practices

```vb
' ✅ Good: Await all the way
Public Async Function ProcessOrderAsync(orderId As Integer) As Task(Of Boolean)
    Dim order = Await GetOrderAsync(orderId)
    Await ValidateOrderAsync(order)
    Await SaveOrderAsync(order)
    Return True
End Function

' ❌ Bad: Blocking on async (deadlock risk)
Public Function ProcessOrder(orderId As Integer) As Boolean
    Dim order = GetOrderAsync(orderId).Result  ' Can deadlock!
    Return True
End Function

' ✅ Good: ConfigureAwait(False) in libraries
Public Async Function GetDataAsync() As Task(Of String)
    Dim result = Await httpClient.GetStringAsync(url).ConfigureAwait(False)
    Return result
End Function

' Parallel async operations
Dim tasks = New List(Of Task(Of Customer)) From {
    GetCustomerAsync(1),
    GetCustomerAsync(2),
    GetCustomerAsync(3)
}
Dim customers = Await Task.WhenAll(tasks)
```

## Error Handling

### Try-Catch Patterns

```vb
' Modern structured exception handling
Try
    Dim result = Await ProcessDataAsync()
    Return result
Catch ex As ArgumentNullException
    ' Handle specific exception
    logger.LogError(ex, "Null argument in ProcessData")
    Throw
Catch ex As HttpRequestException
    ' Handle another specific exception
    logger.LogError(ex, "HTTP request failed")
    Return Nothing
Catch ex As Exception
    ' Catch-all (use sparingly)
    logger.LogError(ex, "Unexpected error")
    Throw
Finally
    ' Cleanup (always runs)
    connection?.Dispose()
End Try
```

### Exception Filters

```vb
' VB 14+ exception filters
Try
    ProcessData()
Catch ex As IOException When ex.Message.Contains("file not found")
    ' Handle specific IO error
    CreateDefaultFile()
Catch ex As IOException When ex.Message.Contains("access denied")
    ' Handle different IO error
    RequestPermissions()
End Try
```

### Custom Exceptions

```vb
' Define custom exception
Public Class CustomerNotFoundException
    Inherits Exception

    Public Property CustomerId As Integer

    Public Sub New(customerId As Integer)
        MyBase.New($"Customer {customerId} not found")
        Me.CustomerId = custo

Related in toolchain