-
Notifications
You must be signed in to change notification settings - Fork 0
Result Type
This library provides robust result types for implementing railway-oriented programming (ROP) patterns in C#. The
Result<TValue> struct and Result static class enable explicit, exception-free error handling while adhering to
functional programming principles.
Key Features:
- Immutability & Thread Safety: Instances cannot be modified after creation, ensuring predictable behavior in concurrent scenarios.
- Null Safety: Success values are guaranteed non-null through guard clauses during initialization.
- Value Semantics: Lightweight record struct design minimizes heap allocations and supports equality comparisons.
-
Explicit State Handling: Clear
IsSuccess/IsFailureindicators and pattern matching eliminate ambiguous state checks. -
Error Conversion: Automatic wrapping of exceptions into
ResultErrorfor consistent error handling. -
Seamless Interop: Implicit conversions from values (
TValue), errors (ResultError), and exceptions. -
Extension Methods: Simplified workflows with methods like
Map,Bind, andMatch.
The Result<TValue>.Value and Result<TValue>.Error properties are only available through extension methods as public access to those properties violates the Railway-oriented programming (ROP) principles and the purpose of this library. The Result<TValue> struct provides the following public properties:
| Property | Type | Description |
|---|---|---|
IsSuccess |
bool |
Indicates if the operation succeeded (true = success) |
IsFailure |
bool |
Indicates if the operation failed (true = failure) |
IsDefault |
bool |
True if success value is default forTValue (e.g., 0 for int) |
Following examples are based on the Result static class and Result<TValue> record struct basic use cases. There are extensive extension methods available for Result<TValue> is explained in other pages.
Examples: Basic Success/Failure creation
// Successful result
// Throws `ArgumentNullException` if value is null
Result<int> successResult = Result.Success(42);
Console.WriteLine(successResult.IsSuccess); // true
// Failure result
Result<int> failureResult = Result.Failure<int>("Operation failed");
Console.WriteLine(failureResult.IsFailure); // true
// Failure result from exception
Result<int> exResult = Result.FromException<int>(new Exception("Error"));
Console.WriteLine(exResult.IsFailure); // trueExamples: Implicit Operators
// From value
// Throws `ArgumentNullException` if value is null
Result<int> result = 42;
// From error
Result<int> result = ResultError.New("Error");
// From exception
Result<int> result = new InvalidOperationException();Examples: Error Handling
public Result<int> Divide(int numerator, int denominator)
{
if (denominator == 0)
return Result.Failure<int>("Division by zero");
// implicit conversion to Result<int>
// Throws `ArgumentNullException` if value is null
return numerator / denominator;
}
var result = Divide(10, 0);
Console.WriteLine(result.IsFailure); // true
result.Match(
success: value => Console.WriteLine($"Got value: {value}"), // Skiped
failure: error => Console.WriteLine($"Error: {error.Message}") // Executed
); // Prints: "Error: Division by zero"Inspired by LanguageExt, this library offers a more compact and user-friendly alternative with extensive examples and tutorials.
There is a very detailed YouTube channel with a dedicated video tutorial playlist for this library.
Star this repository and follow me on GitHub to stay informed about new releases and updates. Your support fuels this project's growth!
If my content adds value to your projects, consider supporting me via crypto.
- Bitcoin: bc1qlfljm9mysdtu064z5cf4yq4ddxgdfztgvghw3w
- USDT(TRC20): TJFME9tAnwdnhmqGHDDG5yCs617kyQDV39
Thank you for being part of this community—let’s build smarter, together