Skip to content

Version Ranges

Frank Stüber edited this page Aug 25, 2026 · 1 revision

The following sections provide a more detailed look at the SemanticVersionRange class.

Version Ranges

SemanticVersionRange represents a range of semantic versions with optional lower and upper bounds. Bounds may be inclusive or exclusive.

Creating Version Ranges

Create a bounded range directly:

var range = new SemanticVersionRange(
    minVersion: new SemanticVersion(1, 0, 0),
    includeMinVersion: true,
    maxVersion: new SemanticVersion(2, 0, 0),
    includeMaxVersion: false);

This represents:

[1.0.0,2.0.0)

Create an exact-precedence range from a single version:

var range = new SemanticVersionRange(new SemanticVersion(1, 2, 3));

Console.WriteLine(range); // [1.2.3]

Parsing Version Ranges

Version ranges use interval notation.

var bounded = SemanticVersionRange.Parse("[1.0.0,2.0.0)");
var exact = SemanticVersionRange.Parse("[1.2.3]");
var minimum = SemanticVersionRange.Parse("1.2.3");
var maximum = SemanticVersionRange.Parse("(,2.0.0]");
var unbounded = SemanticVersionRange.Parse("(,)");

The supported forms are:

Syntax Meaning
1.2.3 1.2.3 or higher
[1.2.3] Exact 1.2.3 precedence
[1.0.0,2.0.0) At least 1.0.0, but lower than 2.0.0
(1.0.0,2.0.0] Higher than 1.0.0, up to and including 2.0.0
[1.2.3,) 1.2.3 or higher
(,2.0.0] Up to and including 2.0.0
(,) No lower or upper bound

Square brackets ([ and ]) represent inclusive bounds. Parentheses (( and )) represent exclusive or unbounded bounds.

Note

A plain version such as 1.2.3 represents a minimum version with no upper bound. Use [1.2.3] when you want an exact-precedence range.

As with SemanticVersion, both string and ReadOnlySpan<char> overloads are available:

ReadOnlySpan<char> value = "[1.0.0,2.0.0)";

var range = SemanticVersionRange.Parse(value);

Use TryParse() when invalid range syntax should not throw:

if (SemanticVersionRange.TryParse("[1.0.0,2.0.0)", out var range))
{
    Console.WriteLine(range);
}

Checking Version Ranges

Use Satisfies() to determine whether a version is within a range:

var range = SemanticVersionRange.Parse("[1.0.0,2.0.0)");

Console.WriteLine( range.Satisfies(SemanticVersion.Parse("1.0.0"))); // True
Console.WriteLine(range.Satisfies(SemanticVersion.Parse("1.5.0")));  // True
Console.WriteLine(range.Satisfies(SemanticVersion.Parse("2.0.0")));  // False

Range checks use SemVer precedence. Build metadata therefore does not affect whether a version satisfies a range:

var range = SemanticVersionRange.Parse("[1.0.0]");

Console.WriteLine( range.Satisfies(SemanticVersion.Parse("1.0.0+build.42"))); // True

Range Properties

A semantic version range exposes the following properties:

Property Description
MinVersion Lower version bound, or null if unbounded
MaxVersion Upper version bound, or null if unbounded
IsMinInclusive Indicates whether the lower bound is inclusive
IsMaxInclusive Indicates whether the upper bound is inclusive
HasLowerBound Indicates whether a lower bound exists
HasUpperBound Indicates whether an upper bound exists

Example:

var range = SemanticVersionRange.Parse("[1.2.3,2.0.0)");

Console.WriteLine(range.MinVersion);     // 1.2.3
Console.WriteLine(range.MaxVersion);     // 2.0.0
Console.WriteLine(range.IsMinInclusive); // True
Console.WriteLine(range.IsMaxInclusive); // False
Console.WriteLine(range.HasLowerBound);  // True
Console.WriteLine(range.HasUpperBound);  // True

Formatting Version Ranges

ToString() returns the canonical representation of a range:

Console.WriteLine(SemanticVersionRange.Parse("[1.2.3]"));       // [1.2.3]
Console.WriteLine(SemanticVersionRange.Parse("(1.0.0,2.0.0]")); // (1.0.0,2.0.0]
Console.WriteLine(SemanticVersionRange.Parse("(,)"));           // (,)

A minimum-inclusive range without an upper bound is formatted using the abbreviated form:

var range = SemanticVersionRange.Parse("[1.2.3,)");

Console.WriteLine(range); // 1.2.3

Clone this wiki locally