Examples

Every snippet below was compiled and executed by the V# compiler. The comment is the real output.

A runnable sample is in the repository at samples/hello, which the build itself compiles and runs as an acceptance gate.

Strings that format like C#

using System;

static (string Name, int Score) Best()
{
    return ("ada", 96);
}

var (name, score) = Best();
Console.WriteLine($"{name,-8}|{score:D4}|{score:X}|{score / 7.0:F2}");
// ada     |0096|60|13.71

Alignment, D/X/F specifiers, tuples with element names, and deconstruction — all of it C# semantics, not String.format with a different face. Numeric rendering is culture-free and verified digit-for-digit against .NET 10.

Patterns everywhere

static string Describe(object value)
{
    return value switch
    {
        int n when n < 0        => "negative",
        int n                   => $"int {n}",
        string { Length: > 3 } s => $"long string {s}",
        string s                => $"short {s}",
        null                    => "nothing",
        _                       => "something else",
    };
}
// int 42|negative|short hi|long string hello|nothing

Type patterns, property patterns, when guards, case null, and exhaustive switch expressions.

Values that behave like values

record struct Point(int X, int Y);

Point a = new Point(2, 3);
Point b = a with { Y = 9 };
string near = a is Point { X: > 1, Y: < 5 } ? "near" : "far";
Console.WriteLine($"{a}|{b}|{near}|{a == new Point(2, 3)}");
// Point { X = 2, Y = 3 }|Point { X = 2, Y = 9 }|near|True

record struct gives you the constructor, ToString, structural equality and with — no class, no inheritance, no virtual dispatch.

Slices, ranges and list patterns

int[] numbers = { 3, 1, 4, 1, 5, 9, 2, 6 };
int[] middle = numbers[2..5];

string shape = numbers switch
{
    [var first, .., var last] => $"{first}..{last}",
    [] => "empty",
};
Console.WriteLine($"{shape}|{numbers[^1]}|{middle.Length}|{middle[0]}");
// 3..6|6|3|4

Generics and extension methods

static class Text
{
    public static bool IsAnyOf(this string value, params string[] options)
    {
        foreach (string option in options)
        {
            if (value == option)
            {
                return true;
            }
        }
        return false;
    }

    public static T Second<T>(this T[] items)
    {
        return items[1];
    }
}

string[] words = { "compile", "run", "verify" };
Console.WriteLine($"{"run".IsAnyOf("walk", "run")}|{words.Second()}|{Text.IsAnyOf("no", "yes")}");
// True|run|False

Extension methods are a compile-time rewrite to a static call, exactly as C# defines them — the receiver form and the static form are the same method. Type parameters work through arrays, params, ref/out, tuples and nullables, and where constraints are enforced.

async / await

using System;

static class Work
{
    public static async Task<int> Fetch(int id)
    {
        return id * 2;
    }

    public static async Task<string> Run()
    {
        int first = await Fetch(21);
        int second = await Fetch(50);
        return $"{first}|{second}";
    }
}

Console.WriteLine(await Work.Run());
// 42|100

Task<T> is java.util.concurrent.Future<T> — not a lookalike. Work runs on a virtual thread and await is the only supported join, with a bounded wait; the JDK's own blocking Get()/Join() are compile errors, because they wait outside that bound. The mapping is described in docs/ASYNC.md.

Exceptions

static string Parse(string text)
{
    try
    {
        checked
        {
            int value = int.Parse(text);
            return $"ok {value * 2}";
        }
    }
    catch (OverflowException)
    {
        return "overflow";
    }
    catch (FormatException)
    {
        return "not a number";
    }
    finally
    {
        Console.Write("[done]");
    }
}

Console.WriteLine($"{Parse("21")}|{Parse("x")}");
// [done][done]ok 42|not a number

checked arithmetic, C#'s exception types, and try/catch/finally over real JVM exception tables. JDK exceptions can be caught and thrown directly.

Calling the JDK

Examples of using the JDK from V# and calling V# output from Java are on the About V# page.