Skip to content
AgileLogics
6 min read

Mixing Visual Basic and C#

Prerequisites: Namespaces, projects, and NuGet

Visual Basic and C# compile to the same IL, so a solution can contain projects in both languages that reference each other freely. This is the most common way teams modernize VB applications: keep the working VB code, and write new libraries in C# (or the reverse).

A C# library used from VB

dotnet new classlib -lang C# -o Pricing
dotnet new console -lang VB -o App
dotnet add App reference Pricing
// Pricing/Calculator.cs  (C#)
namespace Pricing;

public static class Calculator
{
    public static decimal WithTax(decimal net, decimal rate = 0.2m) => net * (1 + rate);
}

public record Product(string Name, decimal Price);
' illustrative: App/Program.vb, referencing the C# Pricing project
Imports Pricing

Module Program
    Sub Main()
        Console.WriteLine(Calculator.WithTax(100D))
        Console.WriteLine(Calculator.WithTax(100D, rate:=0.1D))

        Dim tea As New Product("Tea", 3.5D)
        Console.WriteLine(tea)
        Console.WriteLine(tea.Name)
    End Sub
End Module
120.0
110.0
Product { Name = Tea, Price = 3.5 }
Tea

Static classes appear as modules, C# optional parameters work with VB named arguments, and C# records are ordinary classes to VB (VB can use them, but can't declare them).

Things to watch for

  • Case sensitivity — C# allows two public members that differ only in case (Value and value); VB can't tell them apart. Mark shared libraries [assembly: CLSCompliant(true)] to get warnings.
  • Newer C# features — some can't be used from VB. For example, ref struct types such as Span(Of T) are rejected: Dim s As Span(Of Integer) gives error BC30668, "Types with embedded references are not supported in this version of your compiler". Keep public APIs meant for VB callers to ordinary classes, arrays, and interfaces.
  • Nullable annotations from C# (string?) are ignored by VB.
  • Events and delegates interoperate fully; VB's Handles works on C# events.

Converting code

Online and IDE converters (for example, the open-source CodeConverter extension for Visual Studio) translate VB to C# and back. They handle most syntax, but always review the result — VB-only behaviors like Integer division with \, CInt rounding, and case-insensitive comparisons (Option Compare Text) need care.

Rules of thumb

  • New shared libraries: C# is the safer choice for long-term tooling and framework support.
  • Existing, working VB code: keep it, add tests, and extend it in VB or alongside C# projects.
  • Keep the boundary simple: plain classes, interfaces, and Tasks work perfectly across languages.