diff --git a/Code/Directory.Packages.props b/Code/Directory.Packages.props
new file mode 100644
index 0000000..a2f4fe0
--- /dev/null
+++ b/Code/Directory.Packages.props
@@ -0,0 +1,20 @@
+
+
+ true
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Code/Light.GuardClauses.AllProjects.sln b/Code/Light.GuardClauses.AllProjects.sln
index 461effb..474b424 100644
--- a/Code/Light.GuardClauses.AllProjects.sln
+++ b/Code/Light.GuardClauses.AllProjects.sln
@@ -23,11 +23,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Light.GuardClauses.SourceCo
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Light.GuardClauses.Source", "Light.GuardClauses.Source\Light.GuardClauses.Source.csproj", "{A7B9AC78-FA4F-4BDE-9DAF-B854408AB843}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Versioning", "Versioning", "{176BEDC4-CFE3-4084-8213-B4EC155A7E38}"
- ProjectSection(SolutionItems) = preProject
- Version.props = Version.props
- EndProjectSection
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Light.GuardClauses.SourceCodeTransformation.Tests", "Light.GuardClauses.SourceCodeTransformation.Tests\Light.GuardClauses.SourceCodeTransformation.Tests.csproj", "{A2067796-F167-47BE-B367-191152DCE230}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plans", "Plans", "{664661A0-3861-486B-87B5-A35A5CC5F7B7}"
@@ -35,6 +30,17 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plans", "Plans", "{664661A0
Plans\issue-114-must-not-be-default-or-empty-for-immutable-array.md = Plans\issue-114-must-not-be-default-or-empty-for-immutable-array.md
EndProjectSection
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionItems", "{8A42A536-E597-454B-BE18-4F62311FA158}"
+ ProjectSection(SolutionItems) = preProject
+ ..\CONTRIBUTING.md = ..\CONTRIBUTING.md
+ ..\README.md = ..\README.md
+ ..\LICENSE = ..\LICENSE
+ Directory.Packages.props = Directory.Packages.props
+ Version.props = Version.props
+ Light.GuardClauses.AllProjects.sln.DotSettings = Light.GuardClauses.AllProjects.sln.DotSettings
+ Light.GuardClauses.sln.DotSettings = Light.GuardClauses.sln.DotSettings
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
diff --git a/Code/Light.GuardClauses.InternalRoslynAnalyzers.Tests/Light.GuardClauses.InternalRoslynAnalyzers.Tests.csproj b/Code/Light.GuardClauses.InternalRoslynAnalyzers.Tests/Light.GuardClauses.InternalRoslynAnalyzers.Tests.csproj
index c15326f..249d20e 100644
--- a/Code/Light.GuardClauses.InternalRoslynAnalyzers.Tests/Light.GuardClauses.InternalRoslynAnalyzers.Tests.csproj
+++ b/Code/Light.GuardClauses.InternalRoslynAnalyzers.Tests/Light.GuardClauses.InternalRoslynAnalyzers.Tests.csproj
@@ -1,4 +1,4 @@
-
+net8.0
@@ -6,10 +6,10 @@
-
-
-
-
+
+
+
+
diff --git a/Code/Light.GuardClauses.InternalRoslynAnalyzers/Light.GuardClauses.InternalRoslynAnalyzers.csproj b/Code/Light.GuardClauses.InternalRoslynAnalyzers/Light.GuardClauses.InternalRoslynAnalyzers.csproj
index 1df3b66..83d7c0a 100644
--- a/Code/Light.GuardClauses.InternalRoslynAnalyzers/Light.GuardClauses.InternalRoslynAnalyzers.csproj
+++ b/Code/Light.GuardClauses.InternalRoslynAnalyzers/Light.GuardClauses.InternalRoslynAnalyzers.csproj
@@ -1,4 +1,4 @@
-
+netstandard2.0
@@ -6,7 +6,7 @@
-
+
\ No newline at end of file
diff --git a/Code/Light.GuardClauses.Performance/Light.GuardClauses.Performance.csproj b/Code/Light.GuardClauses.Performance/Light.GuardClauses.Performance.csproj
index cbf1418..30ed96d 100644
--- a/Code/Light.GuardClauses.Performance/Light.GuardClauses.Performance.csproj
+++ b/Code/Light.GuardClauses.Performance/Light.GuardClauses.Performance.csproj
@@ -1,4 +1,4 @@
-
+Exe
@@ -8,7 +8,7 @@
-
+
\ No newline at end of file
diff --git a/Code/Light.GuardClauses.Source/Light.GuardClauses.Source.csproj b/Code/Light.GuardClauses.Source/Light.GuardClauses.Source.csproj
index 0f9b090..26e356d 100644
--- a/Code/Light.GuardClauses.Source/Light.GuardClauses.Source.csproj
+++ b/Code/Light.GuardClauses.Source/Light.GuardClauses.Source.csproj
@@ -1,4 +1,4 @@
-
+netstandard2.0
@@ -10,8 +10,7 @@
-
-
+
\ No newline at end of file
diff --git a/Code/Light.GuardClauses.SourceCodeTransformation.Tests/Light.GuardClauses.SourceCodeTransformation.Tests.csproj b/Code/Light.GuardClauses.SourceCodeTransformation.Tests/Light.GuardClauses.SourceCodeTransformation.Tests.csproj
index 75dd49f..7b64377 100644
--- a/Code/Light.GuardClauses.SourceCodeTransformation.Tests/Light.GuardClauses.SourceCodeTransformation.Tests.csproj
+++ b/Code/Light.GuardClauses.SourceCodeTransformation.Tests/Light.GuardClauses.SourceCodeTransformation.Tests.csproj
@@ -1,16 +1,16 @@
-
+
- net6.0
+ net8.0false
-
-
-
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/Code/Light.GuardClauses.SourceCodeTransformation.Tests/ParseCSharpFilesWithRoslynTests.cs b/Code/Light.GuardClauses.SourceCodeTransformation.Tests/ParseCSharpFilesWithRoslynTests.cs
index 00f0f8f..9462f94 100644
--- a/Code/Light.GuardClauses.SourceCodeTransformation.Tests/ParseCSharpFilesWithRoslynTests.cs
+++ b/Code/Light.GuardClauses.SourceCodeTransformation.Tests/ParseCSharpFilesWithRoslynTests.cs
@@ -5,54 +5,56 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Xunit;
-namespace Light.GuardClauses.SourceCodeTransformation.Tests
+namespace Light.GuardClauses.SourceCodeTransformation.Tests;
+
+public static class ParseCSharpWithRoslynTests
{
- public static class ParseCSharpWithRoslynTests
- {
- private static readonly DirectoryInfo CodeDirectory;
+ private static readonly DirectoryInfo CodeDirectory;
- static ParseCSharpWithRoslynTests()
- {
- CodeDirectory = FindCodeDirectory();
- }
+ static ParseCSharpWithRoslynTests() => CodeDirectory = FindCodeDirectory();
- [Fact]
- public static void ParseExpressionExtensionsFile()
- {
- var fileInfo = GetLightGuardClausesFile(@"FrameworkExtensions\ExpressionExtensions.cs");
- var syntaxTree = CSharpSyntaxTree.ParseText(File.ReadAllText(fileInfo.FullName));
- var root = (CompilationUnitSyntax) syntaxTree.GetRoot();
-
- root.Members.Should().NotBeEmpty();
- }
+ [Fact]
+ public static void ParseExpressionExtensionsFile()
+ {
+ var fileInfo = GetLightGuardClausesFile("FrameworkExtensions/ExpressionExtensions.cs");
+ var syntaxTree = CSharpSyntaxTree.ParseText(File.ReadAllText(fileInfo.FullName));
+ var root = (CompilationUnitSyntax) syntaxTree.GetRoot();
- [Fact]
- public static void ParseSpanDelegatesFile()
- {
- var fileInfo = GetLightGuardClausesFile(@"ExceptionFactory\SpanDelegates.cs");
- var syntaxTree = CSharpSyntaxTree.ParseText(File.ReadAllText(fileInfo.FullName), new CSharpParseOptions(LanguageVersion.CSharp7_3, preprocessorSymbols: new[] { "NETSTANDARD2_0" }));
- var root = (CompilationUnitSyntax) syntaxTree.GetRoot();
+ root.Members.Should().NotBeEmpty();
+ }
- root.Members.Should().NotBeEmpty();
- }
+ [Fact]
+ public static void ParseSpanDelegatesFile()
+ {
+ var fileInfo = GetLightGuardClausesFile("ExceptionFactory/SpanDelegates.cs");
+ var syntaxTree = CSharpSyntaxTree.ParseText(
+ File.ReadAllText(fileInfo.FullName),
+ new (LanguageVersion.CSharp7_3, preprocessorSymbols: ["NETSTANDARD2_0"])
+ );
+ var root = (CompilationUnitSyntax) syntaxTree.GetRoot();
+
+ root.Members.Should().NotBeEmpty();
+ }
- private static DirectoryInfo FindCodeDirectory()
+ private static DirectoryInfo FindCodeDirectory()
+ {
+ var currentDirectory = new DirectoryInfo(".");
+ do
{
- var currentDirectory = new DirectoryInfo(".");
- do
+ if (currentDirectory.Name == "Code")
{
- if (currentDirectory.Name == "Code")
- return currentDirectory;
+ return currentDirectory;
+ }
- currentDirectory = currentDirectory.Parent;
- } while (currentDirectory != null);
+ currentDirectory = currentDirectory.Parent;
+ } while (currentDirectory != null);
- throw new InvalidOperationException("This test project does not reside in a folder called \"Code\" (directly or indirectly).");
- }
-
- private static FileInfo GetLightGuardClausesFile(string relativeFilePath)
- {
- return new FileInfo(Path.Combine(CodeDirectory.FullName, "Light.GuardClauses", relativeFilePath));
- }
+ throw new InvalidOperationException(
+ "This test project does not reside in a folder called \"Code\" (directly or indirectly)."
+ );
}
-}
\ No newline at end of file
+
+ private static FileInfo GetLightGuardClausesFile(string relativeFilePath) => new (
+ Path.Combine(CodeDirectory.FullName, "Light.GuardClauses", relativeFilePath)
+ );
+}
diff --git a/Code/Light.GuardClauses.SourceCodeTransformation/Light.GuardClauses.SourceCodeTransformation.csproj b/Code/Light.GuardClauses.SourceCodeTransformation/Light.GuardClauses.SourceCodeTransformation.csproj
index 371827b..d818386 100644
--- a/Code/Light.GuardClauses.SourceCodeTransformation/Light.GuardClauses.SourceCodeTransformation.csproj
+++ b/Code/Light.GuardClauses.SourceCodeTransformation/Light.GuardClauses.SourceCodeTransformation.csproj
@@ -1,4 +1,4 @@
-
+
@@ -10,10 +10,10 @@
-
-
-
-
+
+
+
+
diff --git a/Code/Light.GuardClauses.SourceCodeTransformation/SourceFileMerger.cs b/Code/Light.GuardClauses.SourceCodeTransformation/SourceFileMerger.cs
index a5af7e0..6b162b9 100644
--- a/Code/Light.GuardClauses.SourceCodeTransformation/SourceFileMerger.cs
+++ b/Code/Light.GuardClauses.SourceCodeTransformation/SourceFileMerger.cs
@@ -61,6 +61,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
using System;
using System.Collections;
using System.Collections.Generic;
+using System.Collections.Immutable;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
diff --git a/Code/Light.GuardClauses.Tests/Light.GuardClauses.Tests.csproj b/Code/Light.GuardClauses.Tests/Light.GuardClauses.Tests.csproj
index 34f0e4e..9439778 100644
--- a/Code/Light.GuardClauses.Tests/Light.GuardClauses.Tests.csproj
+++ b/Code/Light.GuardClauses.Tests/Light.GuardClauses.Tests.csproj
@@ -1,23 +1,20 @@
-
+
-
+
-
- net8.0
- false
- 12
- true
-
+
+ net8.0
+ false
+ 12
+ true
+
-
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Code/Light.GuardClauses/Light.GuardClauses.csproj b/Code/Light.GuardClauses/Light.GuardClauses.csproj
index 845a5fe..06bd149 100644
--- a/Code/Light.GuardClauses/Light.GuardClauses.csproj
+++ b/Code/Light.GuardClauses/Light.GuardClauses.csproj
@@ -26,20 +26,17 @@
trueREADME.md
- Light.GuardClauses 13.1.0
+ Light.GuardClauses 14.0.0
--------------------------------
- - new assertions for ImmutableArray<T>: MustNotBeDefaultOrEmpty, MustHaveLength, MustHaveLengthIn, MustHaveMinimumLength, MustHaveMaximumLength
- - new dependency: System.Collections.Immutable
+ - Breaking Change: Check.Contains(string, string, System.StringComparison) now exists in Light.GuardClauses.FrameworkExtensions to avoid conflict with other polyfill libraries
-
-
-
-
-
+
+
+
diff --git a/Code/Version.props b/Code/Version.props
index e4e99d8..199192b 100644
--- a/Code/Version.props
+++ b/Code/Version.props
@@ -1,5 +1,5 @@
- 13.1.0
+ 14.0.0
\ No newline at end of file
diff --git a/Light.GuardClauses.SingleFile.cs b/Light.GuardClauses.SingleFile.cs
index 758820c..ec5c004 100644
--- a/Light.GuardClauses.SingleFile.cs
+++ b/Light.GuardClauses.SingleFile.cs
@@ -1,5 +1,5 @@
/* ------------------------------
- Light.GuardClauses 13.1.0
+ Light.GuardClauses 14.0.0
------------------------------
License information for Light.GuardClauses
@@ -28,6 +28,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
using System;
using System.Collections;
using System.Collections.Generic;
+using System.Collections.Immutable;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
@@ -53,635 +54,531 @@ namespace Light.GuardClauses
internal static class Check
{
///
- /// Ensures that the specified URI is an absolute one, or otherwise throws a .
+ /// Ensures that the string ends with the specified value, or otherwise throws a .
///
- /// The URI to be checked.
+ /// The string to be checked.
+ /// The other string must end with.
+ /// One of the enumeration values that specifies the rules for the search (optional). The default value is .
/// The name of the parameter (optional).
/// The message that will be passed to the resulting exception (optional).
- /// Thrown when is not an absolute URI.
- /// Thrown when is null.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static Uri MustBeAbsoluteUri([NotNull][ValidatedNotNull] this Uri? parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ /// Thrown when does not end with .
+ /// Thrown when or is null.
+ /// Thrown when is not a valid value.
+ public static string MustEndWith([NotNull, ValidatedNotNull] this string? parameter, [NotNull, ValidatedNotNull] string value, StringComparison comparisonType = StringComparison.CurrentCulture, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
{
- if (parameter.MustNotBeNull(parameterName, message).IsAbsoluteUri == false)
+ if (!parameter.MustNotBeNull(parameterName, message).EndsWith(value, comparisonType))
{
- Throw.MustBeAbsoluteUri(parameter, parameterName, message);
+ Throw.StringDoesNotEndWith(parameter, value, comparisonType, parameterName, message);
}
return parameter;
}
///
- /// Ensures that the specified URI is an absolute one, or otherwise throws your custom exception.
+ /// Ensures that the string ends with the specified value, or otherwise throws a .
///
- /// The URI to be checked.
- /// The delegate that creates the exception to be thrown. is passed to this delegate.
- /// Your custom exception thrown when is not an absolute URI, or when is null.
+ /// The string to be checked.
+ /// The other string must end with.
+ /// The delegate that creates your custom exception. and are passed to this delegate.
+ ///
+ /// Your custom exception thrown when does not end with ,
+ /// or when is null,
+ /// or when is null.
+ ///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static Uri MustBeAbsoluteUri([NotNull][ValidatedNotNull] this Uri? parameter, Func exceptionFactory)
+ [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; value:null => halt; exceptionFactory:null => halt")]
+ public static string MustEndWith([NotNull, ValidatedNotNull] this string? parameter, [NotNull, ValidatedNotNull] string value, [NotNull, ValidatedNotNull] Func exceptionFactory)
{
- if (parameter is null || parameter.IsAbsoluteUri == false)
+ // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -- caller might have NRTs turned off
+ if (parameter is null || value is null || !parameter.EndsWith(value))
{
- Throw.CustomException(exceptionFactory, parameter);
+ Throw.CustomException(exceptionFactory, parameter, value!);
}
return parameter;
}
///
- /// Checks if the given is one of the specified .
+ /// Ensures that the string ends with the specified value, or otherwise throws a .
///
- /// The item to be checked.
- /// The collection that might contain the .
- /// Thrown when is null.
+ /// The string to be checked.
+ /// The other string must end with.
+ /// One of the enumeration values that specifies the rules for the search.
+ /// The delegate that creates your custom exception. , , and are passed to this delegate.
+ ///
+ /// Your custom exception thrown when does not end with ,
+ /// or when is null,
+ /// or when is null.
+ ///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("items:null => halt")]
- // ReSharper disable once RedundantNullableFlowAttribute - the attribute has an effect, see Issue72NotNullAttribute tests
- public static bool IsOneOf(this TItem item, [NotNull][ValidatedNotNull] IEnumerable items)
+ [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; value:null => halt; exceptionFactory:null => halt")]
+ public static string MustEndWith([NotNull, ValidatedNotNull] this string? parameter, [NotNull, ValidatedNotNull] string value, StringComparison comparisonType, [NotNull, ValidatedNotNull] Func exceptionFactory)
{
- if (items is ICollection collection)
- {
- return collection.Contains(item);
- }
-
- if (items is string @string && item is char character)
+ // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -- caller might have NRTs turned off
+ if (parameter is null || value is null || !parameter.EndsWith(value, comparisonType))
{
- return @string.IndexOf(character) != -1;
+ Throw.CustomException(exceptionFactory, parameter, value!, comparisonType);
}
- return items.MustNotBeNull(nameof(items)).ContainsViaForeach(item);
+ return parameter;
}
///
- /// Ensures that the collection does not contain the specified item, or otherwise throws an .
+ /// Ensures that the specified URI has the "http" or "https" scheme, or otherwise throws an .
///
- /// The collection to be checked.
- /// The item that must not be part of the collection.
+ /// The URI to be checked.
/// The name of the parameter (optional).
/// The message that will be passed to the resulting exception (optional).
- /// Thrown when contains .
+ /// Thrown when uses a different scheme than "http" or "https".
+ /// Thrown when is relative and thus has no scheme.
/// Thrown when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static TCollection MustNotContain([NotNull][ValidatedNotNull] this TCollection? parameter, TItem item, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- where TCollection : class, IEnumerable
+ public static Uri MustBeHttpOrHttpsUrl([NotNull][ValidatedNotNull] this Uri? parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
{
- if (parameter is ICollection collection)
- {
- if (collection.Contains(item))
- {
- Throw.ExistingItem(parameter, item, parameterName, message);
- }
-
- return parameter;
- }
-
- if (parameter.MustNotBeNull(parameterName, message).Contains(item))
+ if (parameter.MustBeAbsoluteUri(parameterName, message).Scheme.Equals("https") == false && parameter.Scheme.Equals("http") == false)
{
- Throw.ExistingItem(parameter, item, parameterName, message);
+ Throw.UriMustHaveOneSchemeOf(parameter, ["https", "http"], parameterName, message);
}
return parameter;
}
///
- /// Ensures that the collection does not contain the specified item, or otherwise throws your custom exception.
+ /// Ensures that the specified URI has the "http" or "https" scheme, or otherwise throws your custom exception.
///
- /// The collection to be checked.
- /// The item that must not be part of the collection.
- /// The delegate that creates your custom exception. and are passed to this delegate.
- /// Your custom exception thrown when contains .
+ /// The URI to be checked.
+ /// The delegate that creates the exception to be thrown. is passed to this delegate.
+ /// Your custom exception thrown when uses a different scheme than "http" or "https", or when is a relative URI, or when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static TCollection MustNotContain([NotNull][ValidatedNotNull] this TCollection? parameter, TItem item, Func exceptionFactory)
- where TCollection : class, IEnumerable
+ public static Uri MustBeHttpOrHttpsUrl([NotNull][ValidatedNotNull] this Uri? parameter, Func exceptionFactory)
{
- if (parameter is ICollection collection)
- {
- if (collection.Contains(item))
- {
- Throw.CustomException(exceptionFactory, parameter, item);
- }
-
- return parameter;
- }
-
- if (parameter is null || parameter.Contains(item))
+ if (parameter.MustBeAbsoluteUri(exceptionFactory).Scheme.Equals("https") == false && parameter.Scheme.Equals("http") == false)
{
- Throw.CustomException(exceptionFactory, parameter, item);
+ Throw.CustomException(exceptionFactory, parameter);
}
return parameter;
}
///
- /// Ensures that the string does not contain the specified value, or otherwise throws a .
+ /// Ensures that is within the specified range, or otherwise throws an .
///
- /// The string to be checked.
- /// The string that must not be part of .
+ /// The type of the parameter to be checked.
+ /// The parameter to be checked.
+ /// The range where must be in-between.
/// The name of the parameter (optional).
/// The message that will be passed to the resulting exception (optional).
- /// Thrown when contains .
- /// Thrown when or is null.
+ /// Thrown when is not within .
+ /// Thrown when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static string MustNotContain([NotNull][ValidatedNotNull] this string? parameter, string value, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ public static T MustBeIn([NotNull][ValidatedNotNull] this T parameter, Range range, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ where T : IComparable
{
- if (parameter.MustNotBeNull(parameterName, message).Contains(value.MustNotBeNull(nameof(value), message)))
+ if (!range.IsValueWithinRange(parameter.MustNotBeNullReference(parameterName, message)))
{
- Throw.StringContains(parameter, value, parameterName, message);
+ Throw.MustBeInRange(parameter, range, parameterName, message);
}
return parameter;
}
///
- /// Ensures that the string does not contain the specified value, or otherwise throws your custom exception.
+ /// Ensures that is within the specified range, or otherwise throws your custom exception.
///
- /// The string to be checked.
- /// The string that must not be part of .
- /// The delegate that creates your custom exception (optional). and are passed to this delegate.
- ///
- /// Your custom exception thrown when contains ,
- /// or when is null,
- /// or when is null.
- ///
+ /// The parameter to be checked.
+ /// The range where must be in-between.
+ /// The delegate that creates your custom exception. and are passed to this delegate.
+ /// Your custom exception thrown when is not within , or when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static string MustNotContain([NotNull][ValidatedNotNull] this string? parameter, string value, Func exceptionFactory)
+ [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; exceptionFactory:null => halt")]
+ public static T MustBeIn([NotNull][ValidatedNotNull] this T parameter, Range range, Func, Exception> exceptionFactory)
+ where T : IComparable
{
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - caller might have NRTs turned off
- if (parameter is null || value is null || parameter.Contains(value))
+ if (parameter is null || !range.IsValueWithinRange(parameter))
{
- Throw.CustomException(exceptionFactory, parameter, value!);
+ Throw.CustomException(exceptionFactory, parameter!, range);
}
return parameter;
}
///
- /// Ensures that the string does not contain the specified value, or otherwise throws a .
+ /// Checks if the specified type derives from the other type. Internally, this method uses
+ /// by default so that constructed generic types and their corresponding generic type definitions are regarded as equal.
///
- /// The string to be checked.
- /// The string that must not be part of .
- /// One of the enumeration values that specifies the rules for the search.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when contains .
- /// Thrown when or is null.
- /// Thrown when is not a valid value.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static string MustNotContain([NotNull][ValidatedNotNull] this string? parameter, string value, StringComparison comparisonType, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ /// The type info to be checked.
+ /// The base class that should derive from.
+ /// Thrown when or is null.
+ [ContractAnnotation("type:null => halt; baseClass:null => halt")]
+ public static bool DerivesFrom([NotNull][ValidatedNotNull] this Type type, [NotNull][ValidatedNotNull] Type baseClass)
{
- if (parameter.MustNotBeNull(parameterName, message).IndexOf(value.MustNotBeNull(nameof(value), message), comparisonType) >= 0)
+ baseClass.MustNotBeNull(nameof(baseClass));
+ var currentBaseType = type.MustNotBeNull(nameof(type)).BaseType;
+ while (currentBaseType != null)
{
- Throw.StringContains(parameter, value, comparisonType, parameterName, message);
+ if (currentBaseType.IsEquivalentTypeTo(baseClass))
+ {
+ return true;
+ }
+
+ currentBaseType = currentBaseType.BaseType;
}
- return parameter;
+ return false;
}
///
- /// Ensures that the string does not contain the specified value, or otherwise throws your custom exception.
+ /// Checks if the specified type derives from the other type. This overload uses the specified
+ /// to compare the types.
///
- /// The string to be checked.
- /// The string that must not be part of .
- /// One of the enumeration values that specifies the rules for the search.
- /// The delegate that creates your custom exception (optional). , , and are passed to this delegate.
- ///
- /// Your custom exception thrown when contains ,
- /// or when is null,
- /// or when is null.
- ///
- /// Thrown when is not a valid value.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static string MustNotContain([NotNull][ValidatedNotNull] this string? parameter, string value, StringComparison comparisonType, Func exceptionFactory)
+ /// The type info to be checked.
+ /// The base class that should derive from.
+ /// The equality comparer used to compare the types.
+ /// Thrown when , or , or is null.
+ [ContractAnnotation("type:null => halt; baseClass:null => halt; typeComparer:null => halt")]
+ public static bool DerivesFrom([NotNull][ValidatedNotNull] this Type type, [NotNull][ValidatedNotNull] Type baseClass, [NotNull][ValidatedNotNull] IEqualityComparer typeComparer)
{
- // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - caller might have NRTs turned off
- if (parameter is null || value is null || parameter.IndexOf(value, comparisonType) >= 0)
+ baseClass.MustNotBeNull(nameof(baseClass));
+ typeComparer.MustNotBeNull(nameof(typeComparer));
+ var currentBaseType = type.MustNotBeNull(nameof(type)).BaseType;
+ while (currentBaseType != null)
{
- Throw.CustomException(exceptionFactory, parameter, value!, comparisonType);
+ if (typeComparer.Equals(currentBaseType, baseClass))
+ {
+ return true;
+ }
+
+ currentBaseType = currentBaseType.BaseType;
}
- return parameter;
+ return false;
}
///
- /// Ensures that the does not contain the specified item, or otherwise throws an .
+ /// Checks if the specified character is a letter.
///
- /// The to be checked.
- /// The item that must not be part of the .
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsLetter(this char character) => char.IsLetter(character);
+ ///
+ /// Ensures that the string is shorter than or equal to the specified length, or otherwise throws a .
+ ///
+ /// The string to be checked.
+ /// The length that the string must be shorter than or equal to.
/// The name of the parameter (optional).
/// The message that will be passed to the resulting exception (optional).
- /// Thrown when contains .
- ///
- /// The default instance of cannot contain any items, so this method will not throw for default instances.
- ///
+ /// Thrown when has a length greater than .
+ /// Thrown when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ImmutableArray MustNotContain(this ImmutableArray parameter, T item, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
+ public static string MustBeShorterThanOrEqualTo([NotNull][ValidatedNotNull] this string? parameter, int length, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
{
- if (!parameter.IsDefault && parameter.Contains(item))
+ if (parameter.MustNotBeNull(parameterName, message).Length > length)
{
- Throw.ExistingItem(parameter, item, parameterName, message);
+ Throw.StringNotShorterThanOrEqualTo(parameter, length, parameterName, message);
}
return parameter;
}
///
- /// Ensures that the does not contain the specified item, or otherwise throws your custom exception.
+ /// Ensures that the string is shorter than or equal to the specified length, or otherwise throws your custom exception.
///
- /// The to be checked.
- /// The item that must not be part of the .
- /// The delegate that creates your custom exception. and are passed to this delegate.
- /// Your custom exception thrown when contains .
- ///
- /// The default instance of cannot contain any items, so this method will not throw for default instances.
- ///
+ /// The string to be checked.
+ /// The length that the string must be shorter than or equal to.
+ /// The delegate that creates your custom exception. and are passed to this delegate.
+ /// Your custom exception thrown when is null or when it has a length greater than .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("exceptionFactory:null => halt")]
- public static ImmutableArray MustNotContain(this ImmutableArray parameter, T item, Func, T, Exception> exceptionFactory)
+ [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
+ public static string MustBeShorterThanOrEqualTo([NotNull][ValidatedNotNull] this string? parameter, int length, Func exceptionFactory)
{
- if (!parameter.IsDefault && parameter.Contains(item))
+ if (parameter is null || parameter.Length > length)
{
- Throw.CustomException(exceptionFactory, parameter, item);
+ Throw.CustomException(exceptionFactory, parameter, length);
}
return parameter;
}
///
- /// Checks if the specified string is trimmed at the end, i.e. it does not end with
- /// white space characters. Inputting an empty string will return true.
- ///
- /// The string to be checked.
- ///
- /// The value indicating whether true or false should be returned from this method when the
- /// is null. The default value is true.
- ///
- ///
- /// True if the is trimmed at the end, else false.
- /// An empty string will result in true.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool IsTrimmedAtEnd(this string? parameter, bool regardNullAsTrimmed = true) => parameter is null ? regardNullAsTrimmed : parameter.AsSpan().IsTrimmedAtEnd();
- ///
- /// Checks if the specified character span is trimmed at the end, i.e. it does not end with
- /// white space characters. Inputting an empty span will return true.
- ///
- /// The character span to be checked.
- ///
- /// True if the is trimmed at the end, else false.
- /// An empty span will result in true.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool IsTrimmedAtEnd(this ReadOnlySpan parameter) => parameter.Length == 0 || !parameter[parameter.Length - 1].IsWhiteSpace();
- ///
- /// Ensures that the collection has the specified number of items, or otherwise throws an .
+ /// Ensures that the span is shorter than or equal to the specified length, or otherwise throws an .
///
- /// The collection to be checked.
- /// The number of items the collection must have.
+ /// The span to be checked.
+ /// The length value that the span must be shorter than or equal to.
/// The name of the parameter (optional).
/// The message that will be passed to the resulting exception (optional).
- /// Thrown when does not have the specified number of items.
- /// Thrown when is null.
+ /// Thrown when is longer than .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static TCollection MustHaveCount([NotNull][ValidatedNotNull] this TCollection? parameter, int count, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- where TCollection : class, IEnumerable
+ public static Span MustBeShorterThanOrEqualTo(this Span parameter, int length, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
{
- if (parameter!.Count(parameterName, message) != count)
- {
- Throw.InvalidCollectionCount(parameter, count, parameterName, message);
- }
-
+ ((ReadOnlySpan)parameter).MustBeShorterThanOrEqualTo(length, parameterName, message);
return parameter;
}
///
- /// Ensures that the collection has the specified number of items, or otherwise throws your custom exception.
+ /// Ensures that the span is shorter than or equal to the specified length, or otherwise throws your custom exception.
///
- /// The collection to be checked.
- /// The number of items the collection must have.
- /// The delegate that creates your custom exception. and are passed to this delegate.
- /// Your custom exception thrown when does not have the specified number of items, or when is null.
+ /// The span to be checked.
+ /// The length value that the span must be shorter than or equal to.
+ /// The delegate that creates your custom exception. and are passed to it.
+ /// Your custom exception thrown when is longer than .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static TCollection MustHaveCount([NotNull][ValidatedNotNull] this TCollection? parameter, int count, Func exceptionFactory)
- where TCollection : class, IEnumerable
+ public static Span MustBeShorterThanOrEqualTo(this Span parameter, int length, SpanExceptionFactory exceptionFactory)
{
- if (parameter is null || parameter.Count() != count)
+ if (parameter.Length > length)
{
- Throw.CustomException(exceptionFactory, parameter, count);
+ Throw.CustomSpanException(exceptionFactory, parameter, length);
}
return parameter;
}
///
- /// Ensures that the collection is not null or empty, or otherwise throws an .
+ /// Ensures that the span is shorter than or equal to the specified length, or otherwise throws an .
///
- /// The collection to be checked.
+ /// The span to be checked.
+ /// The length value that the span must be shorter than or equal to.
/// The name of the parameter (optional).
/// The message that will be passed to the resulting exception (optional).
- /// Thrown when has no items.
- /// Thrown when is null.
+ /// Thrown when is longer than .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static TCollection MustNotBeNullOrEmpty([NotNull][ValidatedNotNull] this TCollection? parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- where TCollection : class, IEnumerable
+ public static ReadOnlySpan MustBeShorterThanOrEqualTo(this ReadOnlySpan parameter, int length, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
{
- if (parameter.Count(parameterName, message) == 0)
+ if (parameter.Length > length)
{
- Throw.EmptyCollection(parameterName, message);
+ Throw.SpanMustBeShorterThanOrEqualTo(parameter, length, parameterName, message);
}
return parameter;
}
///
- /// Ensures that the collection is not null or empty, or otherwise throws your custom exception.
+ /// Ensures that the span is shorter than or equal to the specified length, or otherwise throws your custom exception.
///
- /// The collection to be checked.
- /// The delegate that creates your custom exception.
- /// Thrown when has no items, or when is null.
+ /// The span to be checked.
+ /// The length value that the span must be shorter than or equal to.
+ /// The delegate that creates your custom exception. and are passed to it.
+ /// Your custom exception thrown when is longer than .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static TCollection MustNotBeNullOrEmpty([NotNull][ValidatedNotNull] this TCollection? parameter, Func exceptionFactory)
- where TCollection : class, IEnumerable
+ public static ReadOnlySpan MustBeShorterThanOrEqualTo(this ReadOnlySpan parameter, int length, ReadOnlySpanExceptionFactory exceptionFactory)
{
- if (parameter is null || parameter.Count() == 0)
+ if (parameter.Length > length)
{
- Throw.CustomException(exceptionFactory, parameter);
+ Throw.CustomSpanException(exceptionFactory, parameter, length);
}
return parameter;
}
///
- /// Ensures that the specified string is not null or empty, or otherwise throws an or .
+ /// Checks if the specified is true and throws an in this case.
///
- /// The string to be checked.
+ /// The condition to be checked. The exception is thrown when it is true.
/// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when is an empty string.
- /// Thrown when is null.
+ /// The message that will be passed to the (optional).
+ /// Thrown when is true.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static string MustNotBeNullOrEmpty([NotNull][ValidatedNotNull] this string? parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ public static void InvalidArgument(bool condition, string? parameterName = null, string? message = null)
{
- if (parameter is null)
- {
- Throw.ArgumentNull(parameterName, message);
- }
-
- if (parameter.Length == 0)
+ if (condition)
{
- Throw.EmptyString(parameterName, message);
+ Throw.Argument(parameterName, message);
}
-
- return parameter;
}
///
- /// Ensures that the specified string is not null or empty, or otherwise throws your custom exception.
+ /// Checks if the specified is true and throws your custom exception in this case.
///
- /// The string to be checked.
- /// The delegate that creates your custom exception. is passed to this delegate.
- /// Your custom exception thrown when is an empty string or null.
+ /// The condition to be checked. The exception is thrown when it is true.
+ /// The delegate that creates your custom exception.
+ /// Your custom exception thrown when is true.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; exceptionFactory:null => halt")]
- public static string MustNotBeNullOrEmpty([NotNull][ValidatedNotNull] this string? parameter, Func exceptionFactory)
+ [ContractAnnotation("exceptionFactory:null => halt")]
+ public static void InvalidArgument(bool condition, Func exceptionFactory)
{
- if (parameter.IsNullOrEmpty())
+ if (condition)
{
- Throw.CustomException(exceptionFactory, parameter);
+ Throw.CustomException(exceptionFactory);
}
-
- return parameter;
}
///
- /// Ensures that the URI has one of the specified schemes, or otherwise throws an .
+ /// Checks if the specified is true and throws your custom exception in this case.
///
- /// The URI to be checked.
- /// One of these strings must be equal to the scheme of the URI.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when the scheme is not equal to one of the specified schemes.
- /// Thrown when is relative and thus has no scheme.
- /// Thrown when or is null.
+ /// The condition to be checked. The exception is thrown when it is true.
+ /// The value that is checked in the . This value is passed to the .
+ /// The delegate that creates your custom exception. The is passed to this delegate.
+ /// Your custom exception thrown when is true.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; schemes:null => halt")]
- public static Uri MustHaveOneSchemeOf([NotNull][ValidatedNotNull] this Uri? parameter, IEnumerable schemes, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ [ContractAnnotation("exceptionFactory:null => halt")]
+ public static void InvalidArgument(bool condition, T parameter, Func exceptionFactory)
{
- // ReSharper disable PossibleMultipleEnumeration
- parameter.MustBeAbsoluteUri(parameterName, message);
- if (schemes is ICollection collection)
- {
- if (!collection.Contains(parameter.Scheme))
- {
- Throw.UriMustHaveOneSchemeOf(parameter, schemes, parameterName, message);
- }
-
- return parameter;
- }
-
- if (!schemes.MustNotBeNull(nameof(schemes), message).Contains(parameter.Scheme))
+ if (condition)
{
- Throw.UriMustHaveOneSchemeOf(parameter, schemes, parameterName, message);
+ Throw.CustomException(exceptionFactory, parameter);
}
-
- return parameter;
- // ReSharper restore PossibleMultipleEnumeration
}
///
- /// Ensures that the URI has one of the specified schemes, or otherwise throws your custom exception.
+ /// Ensures that is not within the specified range, or otherwise throws an .
///
- /// The URI to be checked.
- /// One of these strings must be equal to the scheme of the URI.
- /// The delegate that creates your custom exception. and are passed to this delegate.
- /// Your custom exception thrown when the scheme is not equal to one of the specified schemes, or when is a relative URI, or when is null.
- /// Thrown when is null.
- /// The type of the collection containing the schemes.
+ /// The type of the parameter to be checked.
+ /// The parameter to be checked.
+ /// The range where must not be in-between.
+ /// The name of the parameter (optional).
+ /// The message that will be passed to the resulting exception (optional).
+ /// Thrown when is within .
+ /// Thrown when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static Uri MustHaveOneSchemeOf([NotNull][ValidatedNotNull] this Uri? parameter, TCollection schemes, Func exceptionFactory)
- where TCollection : class, IEnumerable
+ public static T MustNotBeIn([NotNull][ValidatedNotNull] this T parameter, Range range, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ where T : IComparable
{
- if (parameter is null || !parameter.IsAbsoluteUri)
- {
- Throw.CustomException(exceptionFactory, parameter, schemes);
- }
-
- if (schemes is ICollection collection)
- {
- if (!collection.Contains(parameter.Scheme))
- {
- Throw.CustomException(exceptionFactory, parameter, schemes);
- }
-
- return parameter;
- }
-
- // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - caller might have NRTs turned off
- if (schemes is null || !schemes.Contains(parameter.Scheme))
+ if (range.IsValueWithinRange(parameter.MustNotBeNullReference(parameterName, message)))
{
- Throw.CustomException(exceptionFactory, parameter, schemes!);
+ Throw.MustNotBeInRange(parameter, range, parameterName, message);
}
return parameter;
}
///
- /// Ensures that the specified is not less than the given value, or otherwise throws an .
+ /// Ensures that is not within the specified range, or otherwise throws your custom exception.
///
- /// The comparable to be checked.
- /// The boundary value that must be less than or equal to .
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when the specified is less than .
- /// Thrown when is null.
+ /// The parameter to be checked.
+ /// The range where must not be in-between.
+ /// The delegate that creates your custom exception. and are passed to this delegate.
+ /// Your custom exception thrown when is within , or when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static T MustBeGreaterThanOrEqualTo([NotNull][ValidatedNotNull] this T parameter, T other, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; exceptionFactory:null => halt")]
+ public static T MustNotBeIn([NotNull][ValidatedNotNull] this T parameter, Range range, Func, Exception> exceptionFactory)
where T : IComparable
{
- if (parameter.MustNotBeNullReference(parameterName, message).CompareTo(other) < 0)
+ // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - caller might have NRTs turned off
+ if (parameter is null || range.IsValueWithinRange(parameter))
{
- Throw.MustBeGreaterThanOrEqualTo(parameter, other, parameterName, message);
+ Throw.CustomException(exceptionFactory, parameter!, range);
}
return parameter;
}
///
- /// Ensures that the specified is not less than the given value, or otherwise throws your custom exception.
+ /// Checks if the given is a generic type that has open generic parameters,
+ /// but is no generic type definition.
///
- /// The comparable to be checked.
- /// The boundary value that must be less than or equal to .
- /// The delegate that creates your custom exception. and are passed to this delegate.
- /// Your custom exception thrown when the specified is less than , or when is null.
+ /// The type to be checked.
+ /// Thrown when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; exceptionFactory:null => halt")]
- public static T MustBeGreaterThanOrEqualTo([NotNull][ValidatedNotNull] this T parameter, T other, Func exceptionFactory)
- where T : IComparable
- {
- // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - caller might have NRTs turned off
- if (parameter is null || parameter.CompareTo(other) < 0)
- {
- Throw.CustomException(exceptionFactory, parameter!, other);
- }
-
- return parameter;
- }
-
+ [ContractAnnotation("type:null => halt")]
+ // ReSharper disable once RedundantNullableFlowAttribute -- NotNull has an effect, see Issue72NotNullAttributeTests
+ public static bool IsOpenConstructedGenericType([NotNull][ValidatedNotNull] this Type type) => type.MustNotBeNull(nameof(type)).IsGenericType && type.ContainsGenericParameters && type.IsGenericTypeDefinition == false;
///
- /// Ensures that the collection has at most the specified number of items, or otherwise throws an .
+ /// Checks if the specified character is a letter or digit.
///
- /// The collection to be checked.
- /// The number of items the collection should have at most.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsLetterOrDigit(this char character) => char.IsLetterOrDigit(character);
+ ///
+ /// Checks if the specified string is trimmed at the end, i.e. it does not end with
+ /// white space characters. Inputting an empty string will return true.
+ ///
+ /// The string to be checked.
+ ///
+ /// The value indicating whether true or false should be returned from this method when the
+ /// is null. The default value is true.
+ ///
+ ///
+ /// True if the is trimmed at the end, else false.
+ /// An empty string will result in true.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsTrimmedAtEnd(this string? parameter, bool regardNullAsTrimmed = true) => parameter is null ? regardNullAsTrimmed : parameter.AsSpan().IsTrimmedAtEnd();
+ ///
+ /// Checks if the specified character span is trimmed at the end, i.e. it does not end with
+ /// white space characters. Inputting an empty span will return true.
+ ///
+ /// The character span to be checked.
+ ///
+ /// True if the is trimmed at the end, else false.
+ /// An empty span will result in true.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsTrimmedAtEnd(this ReadOnlySpan parameter) => parameter.Length == 0 || !parameter[parameter.Length - 1].IsWhiteSpace();
+ ///
+ /// Ensures that the has at most the specified length, or otherwise throws an .
+ ///
+ /// The to be checked.
+ /// The maximum length the should have.
/// The name of the parameter (optional).
/// The message that will be passed to the resulting exception (optional).
- /// Thrown when does not contain at most the specified number of items.
- /// Thrown when is null.
+ /// Thrown when has more than the specified length.
+ /// The default instance of will be treated as having length 0.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static TCollection MustHaveMaximumCount([NotNull][ValidatedNotNull] this TCollection? parameter, int count, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- where TCollection : class, IEnumerable
+ public static ImmutableArray MustHaveMaximumLength(this ImmutableArray parameter, int length, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
{
- if (parameter.Count(parameterName, message) > count)
+ var parameterLength = parameter.IsDefault ? 0 : parameter.Length;
+ if (parameterLength > length)
{
- Throw.InvalidMaximumCollectionCount(parameter, count, parameterName, message);
+ Throw.InvalidMaximumImmutableArrayLength(parameter, length, parameterName, message);
}
return parameter;
}
///
- /// Ensures that the collection has at most the specified number of items, or otherwise throws your custom exception.
+ /// Ensures that the has at most the specified length, or otherwise throws your custom exception.
///
- /// The collection to be checked.
- /// The number of items the collection should have at most.
- /// The delegate that creates your custom exception. and are passed to this delegate.
- /// Your custom exception thrown when does not contain at most the specified number of items, or when is null.
+ /// The to be checked.
+ /// The maximum length the should have.
+ /// The delegate that creates your custom exception. and are passed to this delegate.
+ /// Your custom exception thrown when has more than the specified length.
+ /// The default instance of will be treated as having length 0.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static TCollection MustHaveMaximumCount([NotNull][ValidatedNotNull] this TCollection? parameter, int count, Func exceptionFactory)
- where TCollection : class, IEnumerable
+ public static ImmutableArray MustHaveMaximumLength(this ImmutableArray parameter, int length, Func, int, Exception> exceptionFactory)
{
- if (parameter is null || parameter.Count() > count)
+ var parameterLength = parameter.IsDefault ? 0 : parameter.Length;
+ if (parameterLength > length)
{
- Throw.CustomException(exceptionFactory, parameter, count);
+ Throw.CustomException(exceptionFactory, parameter, length);
}
return parameter;
}
///
- /// Checks if the specified character is a digit.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool IsDigit(this char character) => char.IsDigit(character);
- ///
- /// Checks if the specified is true and throws an in this case.
- ///
- /// The condition to be checked. The exception is thrown when it is true.
- /// The message that will be passed to the .
- /// Thrown when is true.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void InvalidState(bool condition, string? message = null)
- {
- if (condition)
- {
- Throw.InvalidState(message);
- }
- }
-
- ///
- /// Checks if the specified GUID is an empty one.
- ///
- /// The GUID to be checked.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool IsEmpty(this Guid parameter) => parameter == Guid.Empty;
- ///
- /// Ensures that the string is a valid email address using the default email regular expression
- /// defined in , or otherwise throws an .
+ /// Ensures that the specified URI is a relative one, or otherwise throws an .
///
- /// The email address that will be validated.
+ /// The URI to be checked.
/// The name of the parameter (optional).
/// The message that will be passed to the resulting exception (optional).
- /// Thrown when is no valid email address.
+ /// Thrown when is an absolute URI.
/// Thrown when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static string MustBeEmailAddress([NotNull][ValidatedNotNull] this string? parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ public static Uri MustBeRelativeUri([NotNull][ValidatedNotNull] this Uri? parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
{
- if (!parameter.MustNotBeNull(parameterName, message).IsEmailAddress())
+ if (parameter.MustNotBeNull(parameterName, message).IsAbsoluteUri)
{
- Throw.InvalidEmailAddress(parameter, parameterName, message);
+ Throw.MustBeRelativeUri(parameter, parameterName, message);
}
return parameter;
}
///
- /// Ensures that the string is a valid email address using the default email regular expression
- /// defined in , or otherwise throws your custom exception.
+ /// Ensures that the specified URI is a relative one, or otherwise throws your custom exception.
///
- /// The email address that will be validated.
+ /// The URI to be checked.
/// The delegate that creates your custom exception. is passed to this delegate.
- /// Your custom exception thrown when is null or no valid email address.
+ /// Your custom exception thrown when is an absolute URI, or when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static string MustBeEmailAddress([NotNull][ValidatedNotNull] this string? parameter, Func exceptionFactory)
+ public static Uri MustBeRelativeUri([NotNull][ValidatedNotNull] this Uri? parameter, Func exceptionFactory)
{
- if (!parameter.IsEmailAddress())
+ if (parameter is null || parameter.IsAbsoluteUri)
{
Throw.CustomException(exceptionFactory, parameter);
}
@@ -690,178 +587,153 @@ public static string MustBeEmailAddress([NotNull][ValidatedNotNull] this string?
}
///
- /// Ensures that the string is a valid email address using the provided regular expression,
- /// or otherwise throws an .
+ /// Ensures that the specified uses , or otherwise throws an .
///
- /// The email address that will be validated.
- /// The regular expression that determines if the input string is a valid email.
+ /// The date time to be checked.
/// The name of the parameter (optional).
/// The message that will be passed to the resulting exception (optional).
- /// Thrown when is no valid email address.
- /// Thrown when is null.
+ /// Thrown when does not use .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; emailAddressPattern:null => halt")]
- public static string MustBeEmailAddress([NotNull][ValidatedNotNull] this string? parameter, Regex emailAddressPattern, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ public static DateTime MustBeLocal(this DateTime parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
{
- if (!parameter.MustNotBeNull(parameterName, message).IsEmailAddress(emailAddressPattern))
+ if (parameter.Kind != DateTimeKind.Local)
{
- Throw.InvalidEmailAddress(parameter, parameterName, message);
+ Throw.MustBeLocalDateTime(parameter, parameterName, message);
}
return parameter;
}
///
- /// Ensures that the string is a valid email address using the provided regular expression,
- /// or otherwise throws your custom exception.
+ /// Ensures that the specified uses , or otherwise throws your custom exception.
///
- /// The email address that will be validated.
- /// The regular expression that determines if the input string is a valid email.
- /// The delegate that creates your custom exception. and are passed to this delegate.
- /// Your custom exception thrown when is null or no valid email address.
+ /// The date time to be checked.
+ /// The delegate that creates your custom exception. is passed to this delegate.
+ /// Your custom exception thrown when does not use .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; emailAddressPattern:null => halt")]
- public static string MustBeEmailAddress([NotNull][ValidatedNotNull] this string? parameter, Regex emailAddressPattern, Func exceptionFactory)
+ [ContractAnnotation("exceptionFactory:null => halt")]
+ public static DateTime MustBeLocal(this DateTime parameter, Func exceptionFactory)
{
- // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - caller might have NRTs turned off
- if (emailAddressPattern is null || !parameter.IsEmailAddress(emailAddressPattern))
+ if (parameter.Kind != DateTimeKind.Local)
{
- Throw.CustomException(exceptionFactory, parameter, emailAddressPattern!);
+ Throw.CustomException(exceptionFactory, parameter);
}
return parameter;
}
///
- /// Ensures that the string is not a substring of the specified other string, or otherwise throws a .
+ /// Ensures that the string matches the specified regular expression, or otherwise throws a .
///
/// The string to be checked.
- /// The other string that must not contain .
+ /// The regular expression used for pattern matching.
/// The name of the parameter (optional).
/// The message that will be passed to the resulting exception (optional).
- /// Thrown when contains .
- /// Thrown when or is null.
+ /// Thrown when does not match the specified regular expression.
+ /// Thrown when or is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; value:null => halt")]
- public static string MustNotBeSubstringOf([NotNull][ValidatedNotNull] this string? parameter, string value, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; regex:null => halt")]
+ public static string MustMatch([NotNull][ValidatedNotNull] this string? parameter, Regex regex, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
{
- if (value.MustNotBeNull(nameof(value), message).Contains(parameter.MustNotBeNull(parameterName, message)))
+ if (!regex.MustNotBeNull(nameof(regex), message).IsMatch(parameter.MustNotBeNull(parameterName, message)))
{
- Throw.Substring(parameter, value, parameterName, message);
+ Throw.StringDoesNotMatch(parameter, regex, parameterName, message);
}
return parameter;
}
///
- /// Ensures that the string is not a substring of the specified other string, or otherwise throws your custom exception.
+ /// Ensures that the string matches the specified regular expression, or otherwise throws your custom exception.
///
/// The string to be checked.
- /// The other string that must not contain .
- /// The delegate that creates your custom exception. and are passed to this delegate.
+ /// The regular expression used for pattern matching.
+ /// The delegate that creates your custom exception. and are passed to this delegate.
///
- /// Your custom exception thrown when contains ,
+ /// Your custom exception thrown when does not match the specified regular expression,
/// or when is null,
- /// or when is null.
+ /// or when is null.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; value:null => halt")]
- public static string MustNotBeSubstringOf([NotNull][ValidatedNotNull] this string? parameter, string value, Func exceptionFactory)
+ public static string MustMatch([NotNull][ValidatedNotNull] this string? parameter, Regex regex, Func exceptionFactory)
{
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - caller might have NRTs turned off
- if (parameter is null || value is null || value.Contains(parameter))
+ if (parameter is null || regex is null || !regex.IsMatch(parameter))
{
- Throw.CustomException(exceptionFactory, parameter, value!);
+ Throw.CustomException(exceptionFactory, parameter, regex!);
}
return parameter;
}
///
- /// Ensures that the string is not a substring of the specified other string, or otherwise throws a .
+ /// Ensures that the specified is not default or empty, or otherwise throws an .
///
- /// The string to be checked.
- /// The other string that must not contain .
- /// One of the enumeration values that specifies the rules for the search.
+ /// The to be checked.
/// The name of the parameter (optional).
/// The message that will be passed to the resulting exception (optional).
- /// Thrown when contains .
- /// Thrown when or is null.
- /// Thrown when is not a valid value.
+ /// Thrown when is default or empty.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; value:null => halt")]
- public static string MustNotBeSubstringOf([NotNull][ValidatedNotNull] this string? parameter, string value, StringComparison comparisonType, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ public static ImmutableArray MustNotBeDefaultOrEmpty(this ImmutableArray parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
{
- value.MustNotBeNull(nameof(value), message);
- parameter.MustNotBeNull(parameterName, message);
- if (value.IndexOf(parameter, comparisonType) != -1)
+ if (parameter.IsDefaultOrEmpty)
{
- Throw.Substring(parameter, value, comparisonType, parameterName, message);
+ Throw.EmptyCollection(parameterName, message);
}
return parameter;
}
///
- /// Ensures that the string is not a substring of the specified other string, or otherwise throws your custom exception.
+ /// Ensures that the specified is not default or empty, or otherwise throws your custom exception.
///
- /// The string to be checked.
- /// The other string that must not contain .
- /// One of the enumeration values that specifies the rules for the search.
- /// The delegate that creates your custom exception. , , and are passed to this delegate.
- ///
- /// Your custom exception thrown when contains ,
- /// or when is null,
- /// or when is null.
- ///
- /// Thrown when is not a valid value.
+ /// The to be checked.
+ /// The delegate that creates your custom exception. The is passed to this delegate.
+ /// Your custom exception thrown when is default or empty.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; value:null => halt")]
- public static string MustNotBeSubstringOf([NotNull][ValidatedNotNull] this string? parameter, string value, StringComparison comparisonType, Func exceptionFactory)
+ [ContractAnnotation("exceptionFactory:null => halt")]
+ public static ImmutableArray MustNotBeDefaultOrEmpty(this ImmutableArray parameter, Func, Exception> exceptionFactory)
{
- // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - caller might have NRTs turned off
- if (parameter is null || value is null || value.IndexOf(parameter, comparisonType) != -1)
+ if (parameter.IsDefaultOrEmpty)
{
- Throw.CustomException(exceptionFactory, parameter, value!, comparisonType);
+ Throw.CustomException(exceptionFactory, parameter);
}
return parameter;
}
///
- /// Ensures that the specified is approximately equal to the given
+ /// Ensures that the specified is greater than or approximately equal to the given
/// value, using the default tolerance of 0.0001, or otherwise throws an
/// .
///
/// The value to be checked.
- /// The value that should be approximately equal to.
+ /// The value that should be greater than or approximately equal to.
/// The name of the parameter (optional).
/// The message that will be passed to the resulting exception (optional).
///
- /// Thrown when the absolute difference between and is not
- /// less than 0.0001.
+ /// Thrown when is not greater than or approximately equal to .
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double MustBeApproximately(this double parameter, double other, [CallerArgumentExpression(nameof(parameter))] string? parameterName = null, string? message = null) => parameter.MustBeApproximately(other, 0.0001, parameterName, message);
+ public static double MustBeGreaterThanOrApproximately(this double parameter, double other, [CallerArgumentExpression(nameof(parameter))] string? parameterName = null, string? message = null) => parameter.MustBeGreaterThanOrApproximately(other, 0.0001, parameterName, message);
///
- /// Ensures that the specified is approximately equal to the given
+ /// Ensures that the specified is greater than or approximately equal to the given
/// value, using the default tolerance of 0.0001, or otherwise throws an
/// .
///
/// The value to be checked.
- /// The value that should be approximately equal to.
+ /// The value that should be greater than or approximately equal to.
///
/// The delegate that creates your custom exception. and
/// are passed to this delegate.
///
///
- /// Thrown when the absolute difference between and is not
- /// less than 0.0001.
+ /// Thrown when is not greater than or approximately equal to .
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double MustBeApproximately(this double parameter, double other, Func exceptionFactory)
+ public static double MustBeGreaterThanOrApproximately(this double parameter, double other, Func exceptionFactory)
{
- if (!parameter.IsApproximately(other))
+ if (!parameter.IsGreaterThanOrApproximately(other))
{
Throw.CustomException(exceptionFactory, parameter, other);
}
@@ -870,46 +742,46 @@ public static double MustBeApproximately(this double parameter, double other, Fu
}
///
- /// Ensures that the specified is approximately equal to the given
+ /// Ensures that the specified is greater than or approximately equal to the given
/// value, or otherwise throws an .
///
/// The value to be checked.
- /// The value that should be approximately equal to.
+ /// The value that should be greater than or approximately equal to.
/// The tolerance indicating how much the two values may differ from each other.
/// The name of the parameter (optional).
/// The message that will be passed to the resulting exception (optional).
///
- /// Thrown when the absolute difference between and is not
- /// less than .
+ /// Thrown when is not greater than or approximately equal to .
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double MustBeApproximately(this double parameter, double other, double tolerance, [CallerArgumentExpression(nameof(parameter))] string? parameterName = null, string? message = null)
+ public static double MustBeGreaterThanOrApproximately(this double parameter, double other, double tolerance, [CallerArgumentExpression(nameof(parameter))] string? parameterName = null, string? message = null)
{
- if (!parameter.IsApproximately(other, tolerance))
+ if (!parameter.IsGreaterThanOrApproximately(other, tolerance))
{
- Throw.MustBeApproximately(parameter, other, tolerance, parameterName, message);
+ Throw.MustBeGreaterThanOrApproximately(parameter, other, tolerance, parameterName, message);
}
return parameter;
}
///
- /// Ensures that the specified is approximately equal to the given
+ /// Ensures that the specified is greater than or approximately equal to the given
/// value, or otherwise throws your custom exception.
///
/// The value to be checked.
- /// The value that should be approximately equal to.
+ /// The value that should be greater than or approximately equal to.
/// The tolerance indicating how much the two values may differ from each other.
- /// The delegate that creates your custom exception. ,
- /// , and are passed to this delegate.
+ ///
+ /// The delegate that creates your custom exception. ,
+ /// , and are passed to this delegate.
+ ///
///
- /// Your custom exception thrown when the absolute difference between and
- /// is not less than .
+ /// Your custom exception thrown when is not greater than or approximately equal to .
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double MustBeApproximately(this double parameter, double other, double tolerance, Func exceptionFactory)
+ public static double MustBeGreaterThanOrApproximately(this double parameter, double other, double tolerance, Func exceptionFactory)
{
- if (!parameter.IsApproximately(other, tolerance))
+ if (!parameter.IsGreaterThanOrApproximately(other, tolerance))
{
Throw.CustomException(exceptionFactory, parameter, other, tolerance);
}
@@ -918,38 +790,37 @@ public static double MustBeApproximately(this double parameter, double other, do
}
///
- /// Ensures that the specified is approximately equal to the given
+ /// Ensures that the specified is greater than or approximately equal to the given
/// value, using the default tolerance of 0.0001f, or otherwise throws an
/// .
///
/// The value to be checked.
- /// The value that should be approximately equal to.
+ /// The value that should be greater than or approximately equal to.
/// The name of the parameter (optional).
/// The message that will be passed to the resulting exception (optional).
///
- /// Thrown when the absolute difference between and is
- /// not less than 0.0001f.
+ /// Thrown when is not greater than or approximately equal to .
+ ///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float MustBeApproximately(this float parameter, float other, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null) => parameter.MustBeApproximately(other, 0.0001f, parameterName, message);
+ public static float MustBeGreaterThanOrApproximately(this float parameter, float other, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null) => parameter.MustBeGreaterThanOrApproximately(other, 0.0001f, parameterName, message);
///
- /// Ensures that the specified is approximately equal to the given
+ /// Ensures that the specified is greater than or approximately equal to the given
/// value, using the default tolerance of 0.0001, or otherwise throws an
/// .
///
/// The value to be checked.
- /// The value that should be approximately equal to.
+ /// The value that should be greater than or approximately equal to.
///
/// The delegate that creates your custom exception. and
/// are passed to this delegate.
///
///
- /// Thrown when the absolute difference between and is not
- /// less than 0.0001.
+ /// Thrown when is not greater than or approximately equal to .
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float MustBeApproximately(this float parameter, float other, Func exceptionFactory)
+ public static float MustBeGreaterThanOrApproximately(this float parameter, float other, Func exceptionFactory)
{
- if (!parameter.IsApproximately(other))
+ if (!parameter.IsGreaterThanOrApproximately(other))
{
Throw.CustomException(exceptionFactory, parameter, other);
}
@@ -958,48 +829,46 @@ public static float MustBeApproximately(this float parameter, float other, Func<
}
///
- /// Ensures that the specified is approximately equal to the given
+ /// Ensures that the specified is greater than or approximately equal to the given
/// value, or otherwise throws an .
///
/// The value to be checked.
- /// The value that should be approximately equal to.
+ /// The value that should be greater than or approximately equal to.
/// The tolerance indicating how much the two values may differ from each other.
/// The name of the parameter (optional).
/// The message that will be passed to the resulting exception (optional).
///
- /// Thrown when the absolute difference between and is not
- /// less than .
+ /// Thrown when is not greater than or approximately equal to .
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float MustBeApproximately(this float parameter, float other, float tolerance, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ public static float MustBeGreaterThanOrApproximately(this float parameter, float other, float tolerance, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
{
- if (!parameter.IsApproximately(other, tolerance))
+ if (!parameter.IsGreaterThanOrApproximately(other, tolerance))
{
- Throw.MustBeApproximately(parameter, other, tolerance, parameterName, message);
+ Throw.MustBeGreaterThanOrApproximately(parameter, other, tolerance, parameterName, message);
}
return parameter;
}
///
- /// Ensures that the specified is approximately equal to the given
+ /// Ensures that the specified is greater than or approximately equal to the given
/// value, or otherwise throws your custom exception.
///
/// The value to be checked.
- /// The value that should be approximately equal to.
+ /// The value that should be greater than or approximately equal to.
/// The tolerance indicating how much the two values may differ from each other.
///
- /// The delegate that creates your custom exception. , , and
- /// are passed to this delegate.
+ /// The delegate that creates your custom exception. ,
+ /// , and are passed to this delegate.
///
///
- /// Your custom exception thrown when the absolute difference between and
- /// is not less than .
+ /// Your custom exception thrown when is not greater than or approximately equal to .
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float MustBeApproximately(this float parameter, float other, float tolerance, Func exceptionFactory)
+ public static float MustBeGreaterThanOrApproximately(this float parameter, float other, float tolerance, Func exceptionFactory)
{
- if (!parameter.IsApproximately(other, tolerance))
+ if (!parameter.IsGreaterThanOrApproximately(other, tolerance))
{
Throw.CustomException(exceptionFactory, parameter, other, tolerance);
}
@@ -1008,344 +877,389 @@ public static float MustBeApproximately(this float parameter, float other, float
}
///
- /// Ensures that the string ends with the specified value, or otherwise throws a .
+ /// Checks if the specified value is greater than or approximately the same as the other value, using the given tolerance.
///
- /// The string to be checked.
- /// The other string must end with.
- /// One of the enumeration values that specifies the rules for the search (optional). The default value is .
+ /// The first value to compare.
+ /// The second value to compare.
+ /// The tolerance indicating how much the two values may differ from each other.
+ ///
+ /// True if is greater than or if their absolute difference
+ /// is smaller than the given , otherwise false.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsGreaterThanOrApproximately(this double value, double other, double tolerance) => value > other || value.IsApproximately(other, tolerance);
+ ///
+ /// Checks if the specified value is greater than or approximately the same as the other value, using the default tolerance of 0.0001.
+ ///
+ /// The first value to compare.
+ /// The second value to compare.
+ ///
+ /// True if is greater than or if their absolute difference
+ /// is smaller than 0.0001, otherwise false.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsGreaterThanOrApproximately(this double value, double other) => value > other || value.IsApproximately(other);
+ ///
+ /// Checks if the specified value is greater than or approximately the same as the other value, using the given tolerance.
+ ///
+ /// The first value to compare.
+ /// The second value to compare.
+ /// The tolerance indicating how much the two values may differ from each other.
+ ///
+ /// True if is greater than or if their absolute difference
+ /// is smaller than the given , otherwise false.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsGreaterThanOrApproximately(this float value, float other, float tolerance) => value > other || value.IsApproximately(other, tolerance);
+ ///
+ /// Checks if the specified value is greater than or approximately the same as the other value, using the default tolerance of 0.0001f.
+ ///
+ /// The first value to compare.
+ /// The second value to compare.
+ ///
+ /// True if is greater than or if their absolute difference
+ /// is smaller than 0.0001, otherwise false.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsGreaterThanOrApproximately(this float value, float other) => value > other || value.IsApproximately(other);
+ ///
+ /// Ensures that the specified is less than the given value, or otherwise throws an .
+ ///
+ /// The comparable to be checked.
+ /// The boundary value that must be greater than .
/// The name of the parameter (optional).
/// The message that will be passed to the resulting exception (optional).
- /// Thrown when does not end with .
- /// Thrown when or is null.
- /// Thrown when is not a valid value.
- public static string MustEndWith([NotNull, ValidatedNotNull] this string? parameter, [NotNull, ValidatedNotNull] string value, StringComparison comparisonType = StringComparison.CurrentCulture, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ /// Thrown when the specified is not less than .
+ /// Thrown when is null.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
+ public static T MustNotBeGreaterThanOrEqualTo([NotNull][ValidatedNotNull] this T parameter, T other, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ where T : IComparable
{
- if (!parameter.MustNotBeNull(parameterName, message).EndsWith(value, comparisonType))
+ if (parameter.MustNotBeNullReference(parameterName, message).CompareTo(other) >= 0)
{
- Throw.StringDoesNotEndWith(parameter, value, comparisonType, parameterName, message);
+ Throw.MustNotBeGreaterThanOrEqualTo(parameter, other, parameterName, message);
}
return parameter;
}
///
- /// Ensures that the string ends with the specified value, or otherwise throws a .
+ /// Ensures that the specified is less than the given value, or otherwise throws your custom exception.
///
- /// The string to be checked.
- /// The other string must end with.
- /// The delegate that creates your custom exception. and are passed to this delegate.
- ///
- /// Your custom exception thrown when does not end with ,
- /// or when is null,
- /// or when is null.
- ///
+ /// The comparable to be checked.
+ /// The boundary value that must be greater than .
+ /// The delegate that creates your custom exception. and are passed to this delegate.
+ /// Your custom exception thrown when the specified is not less than , or when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; value:null => halt; exceptionFactory:null => halt")]
- public static string MustEndWith([NotNull, ValidatedNotNull] this string? parameter, [NotNull, ValidatedNotNull] string value, [NotNull, ValidatedNotNull] Func exceptionFactory)
+ [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; exceptionFactory:null => halt")]
+ public static T MustNotBeGreaterThanOrEqualTo([NotNull][ValidatedNotNull] this T parameter, T other, Func exceptionFactory)
+ where T : IComparable
{
- // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -- caller might have NRTs turned off
- if (parameter is null || value is null || !parameter.EndsWith(value))
+ // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - caller might have NRTs turned off
+ if (parameter is null || parameter.CompareTo(other) >= 0)
{
- Throw.CustomException(exceptionFactory, parameter, value!);
+ Throw.CustomException(exceptionFactory, parameter!, other);
}
return parameter;
}
///
- /// Ensures that the string ends with the specified value, or otherwise throws a .
+ /// Ensures that the value is not one of the specified items, or otherwise throws a .
///
- /// The string to be checked.
- /// The other string must end with.
- /// One of the enumeration values that specifies the rules for the search.
- /// The delegate that creates your custom exception. , , and are passed to this delegate.
- ///
- /// Your custom exception thrown when does not end with ,
- /// or when is null,
- /// or when is null.
- ///
+ /// The value to be checked.
+ /// The items that must not contain the value.
+ /// The name of the parameter (optional).
+ /// The message that will be passed to the resulting exception (optional).
+ /// Thrown when is equal to one of the specified .
+ /// Thrown when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; value:null => halt; exceptionFactory:null => halt")]
- public static string MustEndWith([NotNull, ValidatedNotNull] this string? parameter, [NotNull, ValidatedNotNull] string value, StringComparison comparisonType, [NotNull, ValidatedNotNull] Func exceptionFactory)
+ [ContractAnnotation("items:null => halt")]
+ // ReSharper disable once RedundantNullableFlowAttribute - the attribute has an effect, see Issue72NotNullAttribute tests
+ public static TItem MustNotBeOneOf(this TItem parameter, [NotNull][ValidatedNotNull] IEnumerable items, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
{
- // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -- caller might have NRTs turned off
- if (parameter is null || value is null || !parameter.EndsWith(value, comparisonType))
+ // ReSharper disable PossibleMultipleEnumeration
+ if (parameter.IsOneOf(items.MustNotBeNull(nameof(items), message)))
{
- Throw.CustomException(exceptionFactory, parameter, value!, comparisonType);
+ Throw.ValueIsOneOf(parameter, items, parameterName, message);
}
return parameter;
+ // ReSharper restore PossibleMultipleEnumeration
}
///
- /// Checks if the string contains the specified value using the given comparison type.
- ///
- /// The string to be checked.
- /// The other string.
- /// One of the enumeration values that specifies the rules for the search.
- /// True if contains , else false.
- /// Thrown when or is null.
- /// Thrown when is not a valid value.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("string:null => halt; value:null => halt")]
- public static bool Contains(// ReSharper disable once RedundantNullableFlowAttribute -- Caller might have NRTs turned off
- [NotNull][ValidatedNotNull] this string @string, string value, StringComparison comparisonType) => @string.MustNotBeNull(nameof(@string)).IndexOf(value.MustNotBeNull(nameof(value)), comparisonType) >= 0;
- ///
- /// Ensures that and do not point to the same object instance, or otherwise
- /// throws a .
+ /// Ensures that the value is not one of the specified items, or otherwise throws your custom exception.
///
- /// The first reference to be checked.
- /// The second reference to be checked.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when both and point to the same object.
+ /// The value to be checked.
+ /// The items that must not contain the value.
+ /// The delegate that creates your custom exception. and are passed to this delegate.
+ /// Your custom exception thrown when is equal to one of the specified , or when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static T? MustNotBeSameAs([NoEnumeration] this T? parameter, [NoEnumeration] T? other, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- where T : class
+ [ContractAnnotation("items:null => halt")]
+ public static TItem MustNotBeOneOf(this TItem parameter, [NotNull][ValidatedNotNull] TCollection items, Func exceptionFactory)
+ where TCollection : class, IEnumerable
{
- if (ReferenceEquals(parameter, other))
+ // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - caller might have NRTs turned off
+ if (items is null || parameter.IsOneOf(items))
{
- Throw.SameObjectReference(parameter, parameterName, message);
+ Throw.CustomException(exceptionFactory, parameter, items!);
}
return parameter;
}
///
- /// Ensures that and do not point to the same object instance, or otherwise
- /// throws your custom exception.
+ /// Ensures that the specified URI has the "https" scheme, or otherwise throws an .
///
- /// The first reference to be checked.
- /// The second reference to be checked.
- /// The delegate that creates your custom exception. is passed to this delegate.
- /// Thrown when both and point to the same object.
+ /// The URI to be checked.
+ /// The name of the parameter (optional).
+ /// The message that will be passed to the resulting exception (optional).
+ /// Thrown when uses a different scheme than "https".
+ /// Thrown when is relative and thus has no scheme.
+ /// Thrown when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static T? MustNotBeSameAs([NoEnumeration] this T? parameter, T? other, Func exceptionFactory)
- where T : class
+ [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
+ public static Uri MustBeHttpsUrl([NotNull][ValidatedNotNull] this Uri? parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null) => parameter.MustHaveScheme("https", parameterName, message);
+ ///
+ /// Ensures that the specified URI has the "https" scheme, or otherwise throws your custom exception.
+ ///
+ /// The URI to be checked.
+ /// The delegate that creates the exception to be thrown. is passed to this delegate.
+ /// Your custom exception thrown when uses a different scheme than "https", or when is a relative URI, or when is null.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
+ public static Uri MustBeHttpsUrl([NotNull][ValidatedNotNull] this Uri? parameter, Func exceptionFactory) => parameter.MustHaveScheme("https", exceptionFactory);
+ ///
+ /// Ensures that the specified is not greater than the given value, or otherwise throws an .
+ ///
+ /// The comparable to be checked.
+ /// The boundary value that must be greater than or equal to .
+ /// The name of the parameter (optional).
+ /// The message that will be passed to the resulting exception (optional).
+ /// Thrown when the specified is greater than .
+ /// Thrown when is null.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
+ public static T MustBeLessThanOrEqualTo([NotNull][ValidatedNotNull] this T parameter, T other, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ where T : IComparable
{
- if (ReferenceEquals(parameter, other))
+ if (parameter.MustNotBeNullReference(parameterName, message).CompareTo(other) > 0)
{
- Throw.CustomException(exceptionFactory, parameter);
+ Throw.MustBeLessThanOrEqualTo(parameter, other, parameterName, message);
}
return parameter;
}
///
- /// Ensures that the specified is not approximately equal to the given
- /// value, using the default tolerance of 0.0001, or otherwise throws an
- /// .
- ///
- /// The value to be checked.
- /// The value that should not be approximately equal to.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- ///
- /// Thrown when the absolute difference between and is
- /// less than 0.0001.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double MustNotBeApproximately(this double parameter, double other, [CallerArgumentExpression(nameof(parameter))] string? parameterName = null, string? message = null) => parameter.MustNotBeApproximately(other, 0.0001, parameterName, message);
- ///
- /// Ensures that the specified is not approximately equal to the given
- /// value, using the default tolerance of 0.0001, or otherwise throws an
- /// .
+ /// Ensures that the specified is not greater than the given value, or otherwise throws your custom exception.
///
- /// The value to be checked.
- /// The value that should not be approximately equal to.
- ///
- /// The delegate that creates your custom exception. and
- /// are passed to this delegate.
- ///
- ///
- /// Thrown when the absolute difference between and is
- /// less than 0.0001.
- ///
+ /// The comparable to be checked.
+ /// The boundary value that must be greater than or equal to .
+ /// The delegate that creates your custom exception. and are passed to this delegate.
+ /// Your custom exception thrown when the specified is greater than , or when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double MustNotBeApproximately(this double parameter, double other, Func exceptionFactory)
+ [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; exceptionFactory:null => halt")]
+ public static T MustBeLessThanOrEqualTo([NotNull][ValidatedNotNull] this T parameter, T other, Func exceptionFactory)
+ where T : IComparable
{
- if (parameter.IsApproximately(other))
+ // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - caller might have NRTs turned off
+ if (parameter is null || parameter.CompareTo(other) > 0)
{
- Throw.CustomException(exceptionFactory, parameter, other);
+ Throw.CustomException(exceptionFactory, parameter!, other);
}
return parameter;
}
///
- /// Ensures that the specified is not approximately equal to the given
- /// value, or otherwise throws an .
+ /// Ensures that the string is not null and trimmed at the end, or otherwise throws a .
+ /// Empty strings are regarded as trimmed.
///
- /// The value to be checked.
- /// The value that should not be approximately equal to.
- /// The tolerance indicating how much the two values may differ from each other.
+ /// The string to be checked.
/// The name of the parameter (optional).
/// The message that will be passed to the resulting exception (optional).
- ///
- /// Thrown when the absolute difference between and is
- /// less than .
+ ///
+ /// Thrown when is not trimmed at the end, i.e. they end with white space characters.
+ /// Empty strings are regarded as trimmed.
///
+ /// Thrown when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double MustNotBeApproximately(this double parameter, double other, double tolerance, [CallerArgumentExpression(nameof(parameter))] string? parameterName = null, string? message = null)
+ [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
+ public static string MustBeTrimmedAtEnd([NotNull][ValidatedNotNull] this string? parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
{
- if (parameter.IsApproximately(other, tolerance))
+ if (!parameter.MustNotBeNull(parameterName, message).IsTrimmedAtEnd())
{
- Throw.MustNotBeApproximately(parameter, other, tolerance, parameterName, message);
+ Throw.NotTrimmedAtEnd(parameter, parameterName, message);
}
return parameter;
}
///
- /// Ensures that the specified is not approximately equal to the given
- /// value, or otherwise throws your custom exception.
+ /// Ensures that the string is not null and trimmed at the end, or otherwise throws your custom exception.
+ /// Empty strings are regarded as trimmed.
///
- /// The value to be checked.
- /// The value that should not be approximately equal to.
- /// The tolerance indicating how much the two values may differ from each other.
- /// The delegate that creates your custom exception. ,
- /// , and are passed to this delegate.
- ///
- /// Your custom exception thrown when the absolute difference between and
- /// is less than .
- ///
+ /// The string to be checked.
+ /// The delegate that creates your custom exception. is passed to this delegate.
+ /// Your custom exception thrown when is null or not trimmed at the end. Empty strings are regarded as trimmed.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double MustNotBeApproximately(this double parameter, double other, double tolerance, Func exceptionFactory)
+ [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
+ public static string MustBeTrimmedAtEnd([NotNull][ValidatedNotNull] this string? parameter, Func exceptionFactory)
{
- if (parameter.IsApproximately(other, tolerance))
+ if (parameter is null || !parameter.AsSpan().IsTrimmedAtEnd())
{
- Throw.CustomException(exceptionFactory, parameter, other, tolerance);
+ Throw.CustomException(exceptionFactory, parameter);
}
return parameter;
}
///
- /// Ensures that the specified is not approximately equal to the given
- /// value, using the default tolerance of 0.0001f, or otherwise throws an
- /// .
+ /// Checks if the specified is true and throws an in this case.
///
- /// The value to be checked.
- /// The value that should not be approximately equal to.
+ /// The condition to be checked. The exception is thrown when it is true.
+ /// The message that will be passed to the .
+ /// Thrown when is true.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void InvalidState(bool condition, string? message = null)
+ {
+ if (condition)
+ {
+ Throw.InvalidState(message);
+ }
+ }
+
+ ///
+ /// Ensures that can be cast to and returns the cast value, or otherwise throws a .
+ ///
+ /// The value to be cast.
/// The name of the parameter (optional).
/// The message that will be passed to the resulting exception (optional).
- ///
- /// Thrown when the absolute difference between and is
- /// less than 0.0001f.
+ /// Thrown when cannot be cast to .
+ /// Thrown when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float MustNotBeApproximately(this float parameter, float other, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null) => parameter.MustNotBeApproximately(other, 0.0001f, parameterName, message);
+ [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
+ public static T MustBeOfType([NotNull, ValidatedNotNull, NoEnumeration] this object? parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ {
+ if (parameter.MustNotBeNull(parameterName, message)is T castValue)
+ return castValue;
+ Throw.InvalidTypeCast(parameter, typeof(T), parameterName, message);
+ return default;
+ }
+
///
- /// Ensures that the specified is not approximately equal to the given
- /// value, using the default tolerance of 0.0001, or otherwise throws an
- /// .
+ /// Ensures that can be cast to and returns the cast value, or otherwise throws your custom exception.
///
- /// The value to be checked.
- /// The value that should not be approximately equal to.
- ///
- /// The delegate that creates your custom exception. and
- /// are passed to this delegate.
- ///
- ///
- /// Thrown when the absolute difference between and is
- /// less than 0.0001.
- ///
+ /// The value to be cast.
+ /// The delegate that creates your custom exception. The is passed to this delegate.
+ /// Your custom exception thrown when cannot be cast to .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float MustNotBeApproximately(this float parameter, float other, Func exceptionFactory)
+ [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; exceptionFactory:null => halt")]
+ public static T MustBeOfType([NotNull, ValidatedNotNull, NoEnumeration] this object? parameter, Func