Wolfgang.Extensions.IEquatable
0.3.0
dotnet add package Wolfgang.Extensions.IEquatable --version 0.3.0
NuGet\Install-Package Wolfgang.Extensions.IEquatable -Version 0.3.0
<PackageReference Include="Wolfgang.Extensions.IEquatable" Version="0.3.0" />
<PackageVersion Include="Wolfgang.Extensions.IEquatable" Version="0.3.0" />
<PackageReference Include="Wolfgang.Extensions.IEquatable" />
paket add Wolfgang.Extensions.IEquatable --version 0.3.0
#r "nuget: Wolfgang.Extensions.IEquatable, 0.3.0"
#:package Wolfgang.Extensions.IEquatable@0.3.0
#addin nuget:?package=Wolfgang.Extensions.IEquatable&version=0.3.0
#tool nuget:?package=Wolfgang.Extensions.IEquatable&version=0.3.0
Wolfgang.Extensions.IEquatable
A collection of extension methods for types that implement IEquatable<T> โ concise membership checks (IsInSet / IsNotInSet) and a fluent NotEqual complement to Equals.
๐ฆ Installation
dotnet add package Wolfgang.Extensions.IEquatable
NuGet Package: Wolfgang.Extensions.IEquatable
๐ License
This project is licensed under the MIT License. See the LICENSE file for details.
๐ Documentation
- GitHub Repository: https://github.com/Chris-Wolfgang/IEquatable-Extensions
- API Documentation: https://Chris-Wolfgang.github.io/IEquatable-Extensions/
- CHANGELOG: CHANGELOG.md
- Contributing Guide: CONTRIBUTING.md
๐ Quick Start
using Wolfgang.Extensions.IEquatable;
// Membership checks against a literal set of items
if (status.IsInSet("active", "pending"))
{
// ...
}
if (statusCode.IsNotInSet(200, 201, 204))
{
// ...
}
// Membership against an existing collection
var allowedRoles = new[] { "admin", "editor", "owner" };
if (currentRole.IsInSet(allowedRoles))
{
// ...
}
// Fluent !Equals
if (lhs.NotEqual(rhs))
{
// ...
}
All methods are pure: they return a bool and never mutate the input or the
set.
Equality semantics depend on the overload:
- Single-pair overloads (
IsInSet(T t1),IsInSet(T t1, T t2),NotEqual(T), ...) usestatic object.Equals(object, object). That call boxes value types and usesObject.Equalsvirtual dispatch โ it does not prefer the strongly-typedIEquatable<T>.Equals(T)overload. A future revision may switch toEqualityComparer<T>.Defaultto avoid both the boxing and the virtual call (tracked separately). - Collection overloads (
params T[],IEnumerable<T>,ICollection<T>) useEnumerable.Contains/ICollection<T>.Contains, both of which route throughEqualityComparer<T>.Default. That comparer does preferIEquatable<T>.Equals(T)whenTimplements it.
โจ Features
The table below is a snapshot of the public API at the time of writing. For the authoritative list (kept in sync with source on every release), see the API documentation.
Methods
| Method | Description |
|---|---|
IsInSet(T t1) |
True when item equals t1. |
IsInSet(T t1, T t2) |
True when item equals any of the two listed values. |
IsInSet(T t1, T t2, T t3) |
True when item equals any of the three listed values. |
IsInSet(params T[] set) |
True when item appears in the provided array. |
IsInSet(IEnumerable<T> set) |
True when item appears in the provided sequence. |
IsInSet(ICollection<T> set) |
True when item appears in the provided collection. Preferred when the call site already has an ICollection<T> โ skips the IEnumerable enumerator boxing path. |
IsNotInSet(...) |
Negation of IsInSet for each of the same overloads. |
NotEqual(T other) |
Fluent !Equals(other) so equality chains read top-to-bottom. |
Overload-set notes
- Nullable annotations. On
net5.0+(and net8.0/net10.0 builds) all parameters are declaredT?so nullability flows through the call site. Onnet462/netstandard2.0builds โ which predate the framework's nullable reference annotations โ they're declared as plainT. The runtime behaviour is identical; only the compile-time analysis differs. - Collection overload preference. When the source is already an
ICollection<T>, theICollection<T>overload callsICollection<T>.Containsdirectly โ for types likeHashSet<T>that's an O(1) hash lookup. When the source is anIEnumerable<T>the enumerable overload delegates toEnumerable.Contains(LINQ), which is O(N) and routes throughEqualityComparer<T>.Default.
Examples
// HTTP status filter
var success = response.StatusCode.IsInSet(200, 201, 204);
// Reverse: anything but a known good code
var problem = response.StatusCode.IsNotInSet(200, 201, 204);
// Role check against a pre-built set
var allowed = new HashSet<string> { "admin", "editor" };
if (user.Role.IsInSet(allowed))
{
// ...
}
// Replace `if (a != b)` with `if (a.NotEqual(b))` when the LHS reads
// awkwardly with a leading negation
if (currentVersion.NotEqual(supportedVersion))
{
return Outdated();
}
๐งช Target Frameworks
| Framework | Supported |
|---|---|
| .NET Framework 4.6.2 | โ |
| .NET Standard 2.0 | โ |
| .NET 8.0 | โ |
| .NET 10.0 | โ |
The package multi-targets to keep the dependency footprint small on the modern runtimes while still supporting legacy .NET Framework consumers.
๐ Code Quality & Static Analysis
This project enforces strict code quality standards through 8 specialized analyzers, an <TreatWarningsAsErrors>true</TreatWarningsAsErrors> Release gate, and custom rules:
Analyzers in Use
- Microsoft.CodeAnalysis.NetAnalyzers โ Built-in .NET analyzers for correctness and performance
- Roslynator.Analyzers โ Advanced refactoring and code quality rules
- AsyncFixer โ Async/await best practices and anti-pattern detection
- Microsoft.VisualStudio.Threading.Analyzers โ Thread safety and async patterns
- Microsoft.CodeAnalysis.BannedApiAnalyzers โ Prevents usage of banned APIs (see
BannedSymbols.txt); the async-blocking bans in the shared list are inert here since the library is fully synchronous - Meziantou.Analyzer โ Comprehensive code quality rules
- SonarAnalyzer.CSharp โ Industry-standard code analysis
- Microsoft.CodeAnalysis.PublicApiAnalyzers โ Tracks the public API surface via
PublicAPI.Shipped.txt/PublicAPI.Unshipped.txt; surfaces additions/removals at compile time as a breaking-change review gate
๐ ๏ธ Building from source
git clone https://github.com/Chris-Wolfgang/IEquatable-Extensions.git
cd IEquatable-Extensions
dotnet restore
dotnet build -c Release
dotnet test -c Release --no-build
Requires the .NET 10.0 SDK (or newer) โ earlier SDKs cannot build the net10.0
target. The tests run against every framework the source supports.
๐ค Contributing
See CONTRIBUTING.md for the development workflow, coding conventions, and PR checklist.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 is compatible. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.6.2
- No dependencies.
-
.NETStandard 2.0
- No dependencies.
-
net10.0
- No dependencies.
-
net8.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.