CLSS.Types.ValueRange
1.1.0
dotnet add package CLSS.Types.ValueRange --version 1.1.0
NuGet\Install-Package CLSS.Types.ValueRange -Version 1.1.0
<PackageReference Include="CLSS.Types.ValueRange" Version="1.1.0" />
paket add CLSS.Types.ValueRange --version 1.1.0
#r "nuget: CLSS.Types.ValueRange, 1.1.0"
// Install CLSS.Types.ValueRange as a Cake Addin
#addin nuget:?package=CLSS.Types.ValueRange&version=1.1.0
// Install CLSS.Types.ValueRange as a Cake Tool
#tool nuget:?package=CLSS.Types.ValueRange&version=1.1.0
CLSS.Types.ValueRange
Problem
Structs can be used as dictionary keys. And a legitimate use case of structs as dictionary keys is to create branching code paths that can be changed at runtime as opposed to switch-case
expression which necessarily requires hard-coding your code paths.
// You can't change these branching conditions at runtime
switch (responseCode)
{
case int n when (200 <= n && n < 300):
Path1();
break;
case int n when (300 <= n && n < 400):
Path2();
break;
case int n when (400 <= n && n < 500):
Path3();
break;
}
// You can change these branching conditions at runtime
public struct IntRange { public int Min; public int Max; }
Dictionary<IntRange, Action> ResponseCodePaths = new Dictionary<IntRange, Action>()
{
[new IntRange { Min = 200, Max = 300 }] = Path1,
[new IntRange { Min = 300, Max = 400 }] = Path2,
[new IntRange { Min = 400, Max = 500 }] = Path3
};
ResponseCodePaths.First(p => p.Key.Min <= responseCode < p.Key.Max)();
// add custom response code range at runtime
ResponseCodePaths[new IntRange { Min = 600, Max = 620 }] = Path4;
The default equality comparison of structs - which would be used by dictionaries when comparing keys - is not very performant, as .NET engineers themselves would readily tell you. In order to mitigate this performance issue, the struct type must implement the IEquatable<T>
interface.
The fairly new ValueTuple
type does this and also allows custom field names, but for the specific use case of value ranges, it is not type-safe. The types that ValueTuple
accepts are not necessarily comparable types. ValueTuple
is also not serializable - an attribute that's undoubtably valuable to Unity developers.
Solution
ValueRange
is a type-safe, serializable generic struct type tailored to semantically represent a range of comparable values. The type of its Min
and Max
fields must satisfy an IComparable<T>
constraint. If the constraint is not met, you will get a compilation error, ensuring that you will never get a runtime error if you use an uncomparable type in the type parameter.
ValueRange
implements IEquatable<T>
and therefore it's ready to be used as dictionary keys.
using System;
Dictionary<ValueRange<Version>, Action> VersionMigrationPaths = new Dictionary<ValueRange<Version>, Action>()
{
[new ValueRange<Version>(Version.Parse("1.0"), Version.Parse("1.4"))] = Path1,
[new ValueRange<Version>(Version.Parse("1.4"), Version.Parse("1.6"))] = Path2,
[new ValueRange<Version>(Version.Parse("1.6"), Version.Parse("2.0"))] = Path3
};
Since version 1.1, this package also includes the Encapsulate
extension method to grow a ValueRange
to include more values. It can take in a params
argument list of IComparable<T>
s or other ValueRange
s.
using CLSS;
var numbers = new int[] { 6, -11, -2, 4, 9 };
var numbersRange = new ValueRange<int>(numbers[0], numbers[0]);
numbersRange = numbersRange.Encapsulate(numbers); // Min: -11, Max: 9
var anotherRange1 = new ValueRange<int>(0, 16);
var anotherRange2 = new ValueRange<int>(-12, 0);
numbersRange = numbersRange.Encapsulate(anotherRange1, anotherRange2); // Min: -12, Max: 16
This package is a part of the C# Language Syntactic Sugar suite.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages (3)
Showing the top 3 NuGet packages that depend on CLSS.Types.ValueRange:
Package | Downloads |
---|---|
CLSS.ExtensionMethods.IComparable.InRange
An extension method to check whether the source value is within a range. A part of the C# Language Syntactic Sugar suite. |
|
CLSS.ExtensionMethods.IComparable.ClampToRange
An extension method to clamp the source value into a range. A part of the C# Language Syntactic Sugar suite. |
|
CLSS.Types.EventLatch
A synchronisation aid object for single-threaded context. A part of the C# Language Syntactic Sugar suite. |
GitHub repositories
This package is not used by any popular GitHub repositories.
- Added Encapsulate extension method.