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.
