CSharpEssentials.These
7.0.0
dotnet add package CSharpEssentials.These --version 7.0.0
NuGet\Install-Package CSharpEssentials.These -Version 7.0.0
<PackageReference Include="CSharpEssentials.These" Version="7.0.0" />
<PackageVersion Include="CSharpEssentials.These" Version="7.0.0" />
<PackageReference Include="CSharpEssentials.These" />
paket add CSharpEssentials.These --version 7.0.0
#r "nuget: CSharpEssentials.These, 7.0.0"
#:package CSharpEssentials.These@7.0.0
#addin nuget:?package=CSharpEssentials.These&version=7.0.0
#tool nuget:?package=CSharpEssentials.These&version=7.0.0
CSharpEssentials.These
These<TError, TValue> is a three-state discriminated union: Left (error only), Right (value only), or Both (error and value together). Unlike Result<T>, it does not treat the presence of an error as an automatic failure. Use it when partial success carries a meaningful value alongside a warning or non-fatal error.
Features
- Three-state union:
Left,Right,Bothwith explicit state flags. - Functional API:
Map,MapLeft,FlatMap,Tap,TapLeft,Match. - Maybe bridges:
GetRight()andGetLeft()returnMaybe<T>without throwing. - Result bridges: Convert to/from
Result<T>in strict or lenient mode. - Collection extensions: Partition a sequence into its three states.
- JSON round trip: Serializes as
{"isLeft":true,"isRight":true,"left":...,"right":...}.
Targets net11.0, net10.0, net9.0 and netstandard2.1. Depends on CSharpEssentials.Results, CSharpEssentials.Maybe and CSharpEssentials.Errors. These<TError, TValue> is a readonly record struct in the CSharpEssentials.These namespace.
Installation
dotnet add package CSharpEssentials.These
Usage
Creating These
using CSharpEssentials.These;
// Error only — no value produced
These<string, int> left = These<string, int>.Left("something went wrong");
// Value only — clean success
These<string, int> right = These<string, int>.Right(42);
// Both — value produced but a warning accompanies it
These<string, int> both = These<string, int>.Both("partial failure", 42);
State Flags
bool isLeft = these.IsLeft; // true when Left only
bool isRight = these.IsRight; // true when Right only
bool isBoth = these.IsBoth; // true when Both
HasLeft is true for Left and Both, HasRight is true for Right and Both, and LeftOrDefault and RightOrDefault give the raw payloads (default when that side is absent). default(These<TError, TValue>) is none of the three states, and Match routes it to onBoth with default values, so create instances through Left, Right or Both.
Map: Transform the Value
Map applies a function to the value. Left passes through unchanged; Both transforms the value while keeping the error.
These<string, int> result = These<string, int>.Right(10)
.Map(n => n * 2); // Right(20)
These<string, int> both = These<string, int>.Both("warn", 10)
.Map(n => n * 2); // Both("warn", 20)
MapLeft: Transform the Error
These<int, string> result = These<string, string>.Left("err")
.MapLeft(e => e.Length); // Left(3)
FlatMap: Chain These
FlatMap sequences operations that return These. When chaining from Both, the original error is kept: a mapper result of Right or Both yields Both(originalError, newValue) (the mapper's own error in a Both is dropped because TError has no combine operator), and a mapper result of Left yields that Left.
These<string, int> result = These<string, int>.Right(5)
.FlatMap(n => n > 0
? These<string, int>.Right(n * 10)
: These<string, int>.Left("non-positive"));
Tap / TapLeft: Side Effects
these
.Tap(v => logger.LogInformation("Value: {V}", v)) // fires on Right or Both
.TapLeft(e => logger.LogWarning("Error: {E}", e)); // fires on Left or Both
Match: Exhaustive Pattern Match
string message = these.Match(
onLeft: error => $"Failed: {error}",
onRight: value => $"OK: {value}",
onBoth: (error, val) => $"Partial: {val} (warning: {error})");
GetRight / GetLeft
Both return Maybe<T> and do not throw on the wrong state.
using CSharpEssentials.Maybe;
Maybe<int> value = these.GetRight(); // Some(42) or None
Maybe<string> error = these.GetLeft(); // Some("msg") or None
GetRight() is Some for Right and Both, GetLeft() is Some for Left and Both. A null payload gives None.
Result Bridge
using CSharpEssentials.Errors;
using CSharpEssentials.ResultPattern;
using CSharpEssentials.These;
// From Result<T>: a success becomes Right, a failure becomes Left with its first error only
Result<int> result = GetSomeResult();
These<Error, int> these = TheseExtensions.FromResult(result);
// To Result<T> — strict: Both is treated as failure (Left wins)
Result<int> strict = these.ToResult();
// To Result<T> — lenient: Both is treated as success (value wins)
Result<int> lenient = these.ToResultLenient();
| Conversion | Left | Right | Both |
|---|---|---|---|
ToResult() |
Failure | Success | Failure |
ToResultLenient() |
Failure | Success | Success |
FromResult never produces Both, and it keeps only the first error of a failed result. Both ToResult methods are defined only for These<Error, TValue>.
Collection Extensions
Partition a sequence into its three buckets in one pass.
IEnumerable<These<string, int>> items = GetItems();
var (lefts, rights, boths) = items.Partition();
// lefts : IReadOnlyList<string>
// rights : IReadOnlyList<int>
// boths : IReadOnlyList<(string, int)>
foreach (string error in lefts)
Console.WriteLine($"Error: {error}");
foreach ((string warning, int value) in boths)
Console.WriteLine($"Value {value} with warning: {warning}");
When to Use These vs Result
| Scenario | Use |
|---|---|
| Operation either succeeds or fails | Result<T> |
| Partial success with a non-fatal warning | These<TError, TValue> |
| Accumulating errors while still producing a value | These<TError, TValue> |
| Enrichment pipelines (value + audit log) | These<TError, TValue> |
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. 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. net11.0 is compatible. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- CSharpEssentials.Errors (>= 7.0.0)
- CSharpEssentials.Maybe (>= 7.0.0)
- CSharpEssentials.Results (>= 7.0.0)
- System.Text.Json (>= 9.0.4)
-
net10.0
- CSharpEssentials.Errors (>= 7.0.0)
- CSharpEssentials.Maybe (>= 7.0.0)
- CSharpEssentials.Results (>= 7.0.0)
-
net11.0
- CSharpEssentials.Errors (>= 7.0.0)
- CSharpEssentials.Maybe (>= 7.0.0)
- CSharpEssentials.Results (>= 7.0.0)
-
net9.0
- CSharpEssentials.Errors (>= 7.0.0)
- CSharpEssentials.Maybe (>= 7.0.0)
- CSharpEssentials.Results (>= 7.0.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on CSharpEssentials.These:
| Package | Downloads |
|---|---|
|
CSharpEssentials
A comprehensive C# library enhancing functional programming capabilities with type-safe monads (Maybe, Result), discriminated unions (Any), and robust error handling. Features include: domain-driven design support, enhanced Entity Framework integration, testable time management, JSON utilities, and LINQ extensions. Built for modern C# development with focus on maintainability, testability, and functional programming principles. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 7.0.0 | 117 | 10/20/2026 |
| 6.5.2 | 120 | 10/10/2026 |
| 6.5.1 | 123 | 10/10/2026 |
| 6.5.0 | 125 | 10/9/2026 |
| 6.4.0 | 118 | 10/9/2026 |
| 6.3.0 | 119 | 10/8/2026 |
| 6.2.0 | 126 | 10/8/2026 |
| 6.1.0 | 135 | 10/7/2026 |
| 6.0.0 | 124 | 10/7/2026 |
| 5.2.1 | 123 | 10/7/2026 |
| 5.2.0 | 130 | 10/7/2026 |
| 5.1.0 | 122 | 10/7/2026 |
| 5.0.0 | 118 | 10/6/2026 |
| 4.1.0 | 129 | 10/6/2026 |
| 4.0.0 | 122 | 10/5/2026 |
| 3.2.3 | 295 | 5/31/2026 |
| 3.2.2 | 142 | 5/31/2026 |