diff --git a/README.md b/README.md index 30a29c1..ee08d0f 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,210 @@ # NetEvolve.Arguments -Provides a set of backward compatible argument `throw` helper methods added in the latest .NET versions. -Especially intended for projects with multiple `TargetFrameworks`, for usage, standardization and maintainability. -## Method Overview -The following methods are currently provided. +[![License](https://img.shields.io/github/license/dailydevops/arguments)](LICENSE) +[![Build Status](https://github.com/dailydevops/arguments/actions/workflows/build.yml/badge.svg)](https://github.com/dailydevops/arguments/actions) -### `Argument.ThrowIfEqual(T, T, string?)` -Throws an `ArgumentOutOfRangeException` if the first argument is equal to the second argument. Inplace replacement for [`ArgumentOutOfRangeException.ThrowIfEqual(T, T, string)`](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception.throwifequal), which was introduced with **.NET 8**. +A comprehensive library providing backward-compatible argument validation helper methods (`ThrowIf*`) for .NET projects targeting multiple framework versions. This library enables modern argument validation patterns across legacy and current .NET runtimes, ensuring code consistency and maintainability. -### `Argument.ThrowIfGreaterThan(T, T, string?)` -Throws an `ArgumentOutOfRangeException` if the first argument is greater than the second argument. Inplace replacement for [`ArgumentOutOfRangeException.ThrowIfGreaterThan(T, T, string)`](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception.throwifgreaterthan), which was introduced with **.NET 8**. +## Overview -### `Argument.ThrowIfGreaterThanOrEqual(T, T, string?)` -Throws an `ArgumentOutOfRangeException` if the first argument is greater than or equal to the second argument. Inplace replacement for [`ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(T, T, string)`](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception.throwifgreaterthanorequal), which was introduced with **.NET 8**. +Modern .NET versions (starting with .NET 6) introduced streamlined argument validation methods such as `ArgumentNullException.ThrowIfNull` and `ArgumentOutOfRangeException.ThrowIfEqual`. However, projects targeting multiple frameworks or older .NET versions cannot utilize these convenient methods without conditional compilation or duplicated validation logic. -### `Argument.ThrowIfLessThan(T, T, string?)` -Throws an `ArgumentOutOfRangeException` if the first argument is less than the second argument. Inplace replacement for [`ArgumentOutOfRangeException.ThrowIfLessThan(T, T, string)`](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception.throwiflessthan), which was introduced with **.NET 8**. +**NetEvolve.Arguments** bridges this gap by providing polyfilled implementations of these modern validation methods, allowing developers to write consistent, maintainable argument validation code regardless of the target framework. -### `Argument.ThrowIfLessThanOrEqual(T, T, string?)` -Throws an `ArgumentOutOfRangeException` if the first argument is less than or equal to the second argument. Inplace replacement for [`ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(T, T, string)`](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception.throwiflessthanorequal), which was introduced with **.NET 8**. +## Key Features -### `Argument.ThrowIfNotEqual(T, T, string?)` -Throws an `ArgumentOutOfRangeException` if the first argument is not equal to the second argument. Inplace replacement for [`ArgumentOutOfRangeException.ThrowIfNotEqual(T, T, string)`](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception.throwifnotequal), which was introduced with **.NET 8**. +- **Multi-Framework Support**: Compatible with .NET Standard 2.0, .NET 8.0, .NET 9.0, and .NET 10.0 +- **Zero Runtime Overhead**: Uses conditional compilation to delegate to native implementations where available +- **Drop-in Replacement**: Identical API signatures to native .NET implementations +- **Type-Safe**: Fully generic implementations with proper type constraints +- **Comprehensive Coverage**: Includes null checks, range validations, and equality comparisons -### `Argument.ThrowIfNull(object?, string?)` -Throws an `ArgumentNullException` if the argument is `null`. Inplace replacement for [`ArgumentNullException.ThrowIfNull(object, string)`](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception.throwifnull), which was introduced with **.NET 6**. +## Installation -### `Argument.ThrowIfNull(void*, string?)` -Throws an `ArgumentNullException` if the argument is `null`. Inplace replacement for [`ArgumentNullException.ThrowIfNull(void*, string)`](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception.throwifnull?view=net-8.0#system-argumentnullexception-throwifnull(system-void*-system-string), which was introduced with **.NET 7**. +Install the package via NuGet Package Manager: -### `Argument.ThrowIfNullOrEmpty(string?, string?)` -Throws an `ArgumentNullException` if the argument is `null` or throws an `ArgumentException` if the argument is empty. Inplace replacement for [`ArgumentException.ThrowIfNullOrEmpty(string, string)`](https://learn.microsoft.com/en-us/dotnet/api/system.argumentexception.throwifnullorempty), which was introduced with **.NET 7**. +```bash +dotnet add package NetEvolve.Arguments +``` -### `Argument.ThrowIfNullOrEmpty(IEnumerable?, string?)` (Individuall extension) -Throws an `ArgumentNullException` if the argument is `null` or throws an `ArgumentException` if the argument is empty. +Or via the Package Manager Console: -### `Argument.ThrowIfNullOrWhiteSpace(string?, string?)` -Throws an `ArgumentNullException` if the argument is `null` or throws an `ArgumentException` if the argument is empty or contains only white-space characters. Inplace replacement for [`ArgumentException.ThrowIfNullOrWhiteSpace(string, string)`](https://learn.microsoft.com/en-us/dotnet/api/system.argumentexception.throwifnullorwhitespace), which was introduced with **.NET 8**. \ No newline at end of file +```powershell +Install-Package NetEvolve.Arguments +``` + +## Usage + +Import the namespace in your code: + +```csharp +using NetEvolve.Arguments; +``` + +Then use the validation methods just as you would with native .NET implementations: + +```csharp +public void ProcessData(string data, int count) +{ + Argument.ThrowIfNullOrWhiteSpace(data); + Argument.ThrowIfLessThan(count, 1); + + // Your implementation +} +``` + +## Available Methods + +### Null Validation + +#### `Argument.ThrowIfNull(object?, string?)` +Throws an `ArgumentNullException` if the argument is `null`. + +**Replacement for**: [`ArgumentNullException.ThrowIfNull(object, string)`](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception.throwifnull) (introduced in .NET 6) + +**Example**: +```csharp +public void Process(object data) +{ + Argument.ThrowIfNull(data); +} +``` + +#### `Argument.ThrowIfNull(void*, string?)` +Throws an `ArgumentNullException` if the pointer argument is `null`. + +**Replacement for**: [`ArgumentNullException.ThrowIfNull(void*, string)`](https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception.throwifnull?view=net-8.0#system-argumentnullexception-throwifnull(system-void*-system-string)) (introduced in .NET 7) + +#### `Argument.ThrowIfNullOrEmpty(string?, string?)` +Throws an `ArgumentNullException` if the argument is `null`, or an `ArgumentException` if the argument is an empty string. + +**Replacement for**: [`ArgumentException.ThrowIfNullOrEmpty(string, string)`](https://learn.microsoft.com/en-us/dotnet/api/system.argumentexception.throwifnullorempty) (introduced in .NET 7) + +**Example**: +```csharp +public void Process(string name) +{ + Argument.ThrowIfNullOrEmpty(name); +} +``` + +#### `Argument.ThrowIfNullOrEmpty(IEnumerable?, string?)` +Throws an `ArgumentNullException` if the argument is `null`, or an `ArgumentException` if the collection is empty. + +**Note**: This is a custom extension method not present in the base .NET framework, providing convenient collection validation. + +**Example**: +```csharp +public void Process(IEnumerable items) +{ + Argument.ThrowIfNullOrEmpty(items); +} +``` + +#### `Argument.ThrowIfNullOrWhiteSpace(string?, string?)` +Throws an `ArgumentNullException` if the argument is `null`, or an `ArgumentException` if the argument is empty or contains only white-space characters. + +**Replacement for**: [`ArgumentException.ThrowIfNullOrWhiteSpace(string, string)`](https://learn.microsoft.com/en-us/dotnet/api/system.argumentexception.throwifnullorwhitespace) (introduced in .NET 8) + +**Example**: +```csharp +public void Process(string description) +{ + Argument.ThrowIfNullOrWhiteSpace(description); +} +``` + +### Range Validation + +#### `Argument.ThrowIfEqual(T, T, string?)` +Throws an `ArgumentOutOfRangeException` if the first argument is equal to the second argument. + +**Replacement for**: [`ArgumentOutOfRangeException.ThrowIfEqual(T, T, string)`](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception.throwifequal) (introduced in .NET 8) + +**Example**: +```csharp +public void SetValue(int value) +{ + Argument.ThrowIfEqual(value, 0); // Value must not be zero +} +``` + +#### `Argument.ThrowIfNotEqual(T, T, string?)` +Throws an `ArgumentOutOfRangeException` if the first argument is not equal to the second argument. + +**Replacement for**: [`ArgumentOutOfRangeException.ThrowIfNotEqual(T, T, string)`](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception.throwifnotequal) (introduced in .NET 8) + +#### `Argument.ThrowIfGreaterThan(T, T, string?)` +Throws an `ArgumentOutOfRangeException` if the first argument is greater than the second argument. + +**Replacement for**: [`ArgumentOutOfRangeException.ThrowIfGreaterThan(T, T, string)`](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception.throwifgreaterthan) (introduced in .NET 8) + +**Example**: +```csharp +public void SetAge(int age) +{ + Argument.ThrowIfGreaterThan(age, 150); // Age must be 150 or less +} +``` + +#### `Argument.ThrowIfGreaterThanOrEqual(T, T, string?)` +Throws an `ArgumentOutOfRangeException` if the first argument is greater than or equal to the second argument. + +**Replacement for**: [`ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(T, T, string)`](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception.throwifgreaterthanorequal) (introduced in .NET 8) + +**Example**: +```csharp +public void SetCount(int count, int maximum) +{ + Argument.ThrowIfGreaterThanOrEqual(count, maximum); // Count must be less than maximum +} +``` + +#### `Argument.ThrowIfLessThan(T, T, string?)` +Throws an `ArgumentOutOfRangeException` if the first argument is less than the second argument. + +**Replacement for**: [`ArgumentOutOfRangeException.ThrowIfLessThan(T, T, string)`](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception.throwiflessthan) (introduced in .NET 8) + +**Example**: +```csharp +public void SetCount(int count) +{ + Argument.ThrowIfLessThan(count, 1); // Count must be at least 1 +} +``` + +#### `Argument.ThrowIfLessThanOrEqual(T, T, string?)` +Throws an `ArgumentOutOfRangeException` if the first argument is less than or equal to the second argument. + +**Replacement for**: [`ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(T, T, string)`](https://learn.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception.throwiflessthanorequal) (introduced in .NET 8) + +**Example**: +```csharp +public void SetMinimum(int value, int threshold) +{ + Argument.ThrowIfLessThanOrEqual(value, threshold); // Value must be greater than threshold +} +``` + +## Framework Compatibility + +| Target Framework | Status | Notes | +|-----------------|--------|-------| +| .NET Standard 2.0 | ✅ Supported | Full polyfill implementations | +| .NET 8.0 | ✅ Supported | Delegates to native implementations where available | +| .NET 9.0 | ✅ Supported | Full native delegation | +| .NET 10.0 | ✅ Supported | Full native delegation | + +## Contributing + +Contributions are welcome! Please feel free to submit issues, fork the repository, and create pull requests. + +## License + +This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. + +## Related Resources + +- [Official .NET API Documentation](https://learn.microsoft.com/en-us/dotnet/api/) +- [Argument Validation Best Practices](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/exceptions/) +- [Project Repository](https://github.com/dailydevops/arguments) \ No newline at end of file diff --git a/src/NetEvolve.Arguments/NetEvolve.Arguments.csproj b/src/NetEvolve.Arguments/NetEvolve.Arguments.csproj index d7ba8b7..817ca5a 100644 --- a/src/NetEvolve.Arguments/NetEvolve.Arguments.csproj +++ b/src/NetEvolve.Arguments/NetEvolve.Arguments.csproj @@ -1,6 +1,6 @@ - netstandard2.0;net7.0;net8.0 + netstandard2.0;net8.0;net9.0;net10.0 A library that provides compatible `ThrowIf` methods for .NET / C# for older runtimes. true $(MSBuildProjectName) diff --git a/tests/NetEvolve.Arguments.Tests.Unit/NetEvolve.Arguments.Tests.Unit.csproj b/tests/NetEvolve.Arguments.Tests.Unit/NetEvolve.Arguments.Tests.Unit.csproj index ff7c21f..3167f14 100644 --- a/tests/NetEvolve.Arguments.Tests.Unit/NetEvolve.Arguments.Tests.Unit.csproj +++ b/tests/NetEvolve.Arguments.Tests.Unit/NetEvolve.Arguments.Tests.Unit.csproj @@ -1,6 +1,6 @@  - net8.0;net9.0 + net8.0;net9.0;net10.0 true $(NoWarn);NU1701 true