From 887a47346c744b2074e130cf4ef968e3dc28c9c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=BE=D0=BD=D1=81=D1=82=D0=B0=D0=BD=D1=82=D0=B8?= =?UTF-8?q?=D0=BD=20=D0=94=D1=8C=D1=8F=D1=87=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Wed, 24 Jul 2019 22:01:52 +0300 Subject: [PATCH] Added Ensure extensions for range-related exceptions. Added implementation of IEquatable> to Range struct. Exception check from the constructor of Range struct moved to Ensure extensions so its logic can be reused now. Added more comments to Range struct. Closes #5 and closes #6. Version 0.0.3. --- EnsureExtensions.cs | 69 ++++++++++++++++++++++++++++++++++++++++++ Platform.Ranges.csproj | 17 ++++++++--- README.md | 4 +-- Range.cs | 30 +++++++++++++++--- 4 files changed, 110 insertions(+), 10 deletions(-) create mode 100644 EnsureExtensions.cs diff --git a/EnsureExtensions.cs b/EnsureExtensions.cs new file mode 100644 index 0000000..03be50b --- /dev/null +++ b/EnsureExtensions.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using Platform.Exceptions; + +#pragma warning disable IDE0060 // Remove unused parameter + +namespace Platform.Ranges +{ + public static class EnsureExtensions + { + #region Always + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MaximumArgumentIsGreaterOrEqualToMinimum(this EnsureAlwaysExtensionRoot root, T minimum, T maximum) => MaximumArgumentIsGreaterOrEqualToMinimum(root, minimum, maximum, nameof(maximum)); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MaximumArgumentIsGreaterOrEqualToMinimum(this EnsureAlwaysExtensionRoot root, T minimum, T maximum, string argumentName) + { + if (Comparer.Default.Compare(maximum, minimum) < 0) + { + throw new ArgumentException("Maximum should be greater or equal to minimum.", argumentName); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ArgumentInRange(this EnsureAlwaysExtensionRoot root, T argumentValue, T minimum, T maximum) => ArgumentInRange(root, argumentValue, new Range(minimum, maximum), null); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ArgumentInRange(this EnsureAlwaysExtensionRoot root, T argumentValue, T minimum, T maximum, string argumentName) => ArgumentInRange(root, argumentValue, new Range(minimum, maximum), argumentName); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ArgumentInRange(this EnsureAlwaysExtensionRoot root, T argumentValue, Range range) => ArgumentInRange(root, argumentValue, range, null); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ArgumentInRange(this EnsureAlwaysExtensionRoot root, T argumentValue, Range range, string argumentName) + { + if (!range.ContainsValue(argumentValue)) + { + throw new ArgumentOutOfRangeException(argumentName, argumentValue, $"Argument value [{argumentValue}] is out of range {range}."); + } + } + + #endregion + + #region OnDebug + + [Conditional("DEBUG")] + public static void MaximumArgumentIsGreaterOrEqualToMinimum(this EnsureOnDebugExtensionRoot root, T minimum, T maximum) => Ensure.Always.MaximumArgumentIsGreaterOrEqualToMinimum(minimum, maximum, null); + + [Conditional("DEBUG")] + public static void MaximumArgumentIsGreaterOrEqualToMinimum(this EnsureOnDebugExtensionRoot root, T minimum, T maximum, string argumentName) => Ensure.Always.MaximumArgumentIsGreaterOrEqualToMinimum(minimum, maximum, argumentName); + + [Conditional("DEBUG")] + public static void ArgumentInRange(this EnsureOnDebugExtensionRoot root, T argumentValue, T minimum, T maximum) => Ensure.Always.ArgumentInRange(argumentValue, new Range(minimum, maximum), null); + + [Conditional("DEBUG")] + public static void ArgumentInRange(this EnsureOnDebugExtensionRoot root, T argumentValue, T minimum, T maximum, string argumentName) => Ensure.Always.ArgumentInRange(argumentValue, new Range(minimum, maximum), argumentName); + + [Conditional("DEBUG")] + public static void ArgumentInRange(this EnsureOnDebugExtensionRoot root, T argument, Range range) => Ensure.Always.ArgumentInRange(argument, range, null); + + [Conditional("DEBUG")] + public static void ArgumentInRange(this EnsureOnDebugExtensionRoot root, T argument, Range range, string argumentName) => Ensure.Always.ArgumentInRange(argument, range, argumentName); + + #endregion + } +} diff --git a/Platform.Ranges.csproj b/Platform.Ranges.csproj index ce47cd8..e8d6ce3 100644 --- a/Platform.Ranges.csproj +++ b/Platform.Ranges.csproj @@ -4,15 +4,15 @@ LinksPlatform's Platform.Ranges Class Library Konstantin Diachenko Platform.Ranges - 0.0.2 + 0.0.3 Konstantin Diachenko netstandard2.0 Platform.Ranges Platform.Ranges - LinksPlatform;Ranges;Range - https://raw.githubusercontent.com/linksplatform/Documentation/0a9177c11892ebb2fe467dc3ea9eaf5a5588f610/doc/Avatar-rainbow.png + LinksPlatform;Ranges;Range;EnsureExtensions + https://raw.githubusercontent.com/linksplatform/Documentation/18469f4d033ee9a5b7b84caab9c585acab2ac519/doc/Avatar-rainbow-icon-64x64.png https://github.com/linksplatform/Ranges - https://github.com/linksplatform/Ranges/blob/master/LICENSE + MIT true git git://github.com/linksplatform/Ranges @@ -21,6 +21,15 @@ false true snupkg + Added Ensure extensions for range-related exceptions. +Added implementation of IEquatable<Range<T>> to Range struct. +Exception check from the constructor of Range struct moved to Ensure extensions so its logic can be reused now. +Added more comments to Range struct. +Two issues closed. + + + + diff --git a/README.md b/README.md index 7321dcd..043dd03 100644 --- a/README.md +++ b/README.md @@ -18,10 +18,10 @@ NuGet package: https://www.nuget.org/packages/Platform.Ranges `Range` *class* with `Floor` and `Ceiling` *fields*. -### [mnelsonwhite/Range.NET](https://github.com/mnelsonwhite/Range.NET) +### [mnelsonwhite/Range.NET](https://github.com/mnelsonwhite/Range.NET) `Range` *class* with `Minumum` and `Maximum` *properties*. ### [sdcb/Sdcb.System.Range](https://github.com/sdcb/Sdcb.System.Range) -`Range` *struct* with `Start` and `End` *properties*. +`Range` *struct* with `Start` and `End` *properties*. \ No newline at end of file diff --git a/Range.cs b/Range.cs index 40f06fe..75b064e 100644 --- a/Range.cs +++ b/Range.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Platform.Exceptions; namespace Platform.Ranges { @@ -10,9 +11,10 @@ namespace Platform.Ranges /// /// Based on http://stackoverflow.com/questions/5343006/is-there-a-c-sharp-type-for-representing-an-integer-range /// - public struct Range + public struct Range : IEquatable> { private static readonly Comparer _comparer = Comparer.Default; + private static readonly EqualityComparer _equalityComparer = EqualityComparer.Default; /// /// Returns minimum value of the range. @@ -26,15 +28,27 @@ public struct Range /// public readonly T Maximum; + /// + /// Initializes a new instance of the Range class. + /// Инициализирует новый экземпляр класса Range. + /// + /// Single value for both Minimum and Maximum fields. Одно значение для полей Minimum и Maximum. public Range(T minimumAndMaximum) - : this(minimumAndMaximum, minimumAndMaximum) { + Minimum = minimumAndMaximum; + Maximum = minimumAndMaximum; } + /// + /// Initializes a new instance of the Range class. + /// Инициализирует новый экземпляр класса Range. + /// + /// The minimum value of the range. Минимальное значение диапазона. + /// The maximum value of the range. Максимальное значение диапазона. + /// Thrown when maximum is less than minimum. public Range(T minimum, T maximum) { - if (_comparer.Compare(maximum, minimum) < 0) - throw new ArgumentException("Maximum should be greater or equal to minimum.", nameof(maximum)); + Ensure.Always.MaximumArgumentIsGreaterOrEqualToMinimum(minimum, maximum, nameof(maximum)); Minimum = minimum; Maximum = maximum; @@ -70,5 +84,13 @@ public Range(T minimum, T maximum) /// The child range to test. Дочерний диапазон для проверки. /// True if range is inside, else false. True, если диапазон находится внутри, иначе false. public bool ContainsRange(Range range) => ContainsValue(range.Minimum) && ContainsValue(range.Maximum); + + /// + /// Indicates whether the current range is equal to another range. + /// Определяет, равен ли текущий диапазон другому диапазону. + /// + /// A range to compare with this range. Диапазон для сравнения с этим диапазоном. + /// True if the current range is equal to the other range; otherwise, false. True, если текущий диапазон равен другому диапазону; иначе false. + public bool Equals(Range other) => _equalityComparer.Equals(Minimum, other.Minimum) && _equalityComparer.Equals(Maximum, other.Maximum); } }