QDev.CSharp.LanguageExtensions.Results
1.0.1
dotnet add package QDev.CSharp.LanguageExtensions.Results --version 1.0.1
NuGet\Install-Package QDev.CSharp.LanguageExtensions.Results -Version 1.0.1
<PackageReference Include="QDev.CSharp.LanguageExtensions.Results" Version="1.0.1" />
paket add QDev.CSharp.LanguageExtensions.Results --version 1.0.1
#r "nuget: QDev.CSharp.LanguageExtensions.Results, 1.0.1"
// Install QDev.CSharp.LanguageExtensions.Results as a Cake Addin #addin nuget:?package=QDev.CSharp.LanguageExtensions.Results&version=1.0.1 // Install QDev.CSharp.LanguageExtensions.Results as a Cake Tool #tool nuget:?package=QDev.CSharp.LanguageExtensions.Results&version=1.0.1
Class Result<T, E>
Result<T, E>
is a generic class that encapsulates either a successful result of type T or an error result of type E.
It is commonly used to handle outcomes in a more structured and functional way, ensuring that both success and error
cases are explicitly represented. This class provides methods for functional result handling, allowing developers to work
with results in a functional and expressive manner, whether they are in the "Ok" or "Error" state. It offers a range of
operations for transforming, chaining, and inspecting results, making it a powerful tool for result-based logic in
applications. It is essential to handle exceptions appropriately, especially when using unwrapping methods, to ensure
robust error handling.
This documentation includes extension methods that introduce functional programming features to this class.
Table of Contents
Installation
Using the NuGet package manager console within Visual Studio run the following command:
Install-Package QDev.CSharp.LanguageExtensions.Results
Or using the .NET Core CLI from a terminal window:
dotnet add package QDev.CSharp.LanguageExtensions.Results
Internal Methods
Constructors
This class provides two static constructors for creating instances of successful results (Ok) and error results (Err).
Result<T, E>.Ok(T value)
: Creates a new instance representing a successful result with the provided value.Result<T, E>.Err(E error)
: Creates a new instance representing an error result with the provided error value or message.
Creating Results
// Creating a successful result
Result<int, string> successResult = Result<int, string>.Ok(42);
// Creating an error result
Result<int, string> errorResult = Result<int, string>.Err("Error message");
// Creating an error result as exception
Result<int, ArgumentException> errorResultException = Result<int, ArgumentException>.Err(new ArgumentException("Error message"));
Getters
Ok()
: Retrieve the successful value if the result is successful; otherwise, returns null.Err()
: Retrieve the error value or message if the result is an error; otherwise, returns null.IsOk
: Gets a value indicating whether the result is successful.IsErr
: Gets a value indicating whether the result is an error.
Accessing Values
You can access the value of a result using the Ok()
or Err()
method.
For better result handling, it is recommended to use the 'unwrapers' methods. These methods now throw exceptions in case
of an error, and they require the programmer to handle these errors.
if (successResult.IsOk)
{
int value = successResult.Ok()!.Value;
// Use the successful value
}
else
{
string error = successResult.Err()!;
// Handle the error
}
Logic Operators
And<U>(Result<U, E> result)
: Combines this result with another result of a different type using a logical AND operation.Or<F>(Result<T, F> result)
: Combines this result with another result of a different error type using a logical OR operation.
Examples of AND and OR operators
Both Results are Successful (Ok):
var resultA = Result<int, string>.Ok(42);
var resultB = Result<string, string>.Ok("Success");
var andResult = resultA.And(resultB); // Ok("Success")
var orResult = resultA.Or(resultB); // Ok(42)
First Result is Successful (Ok), Second Result is an Error (Err):
var resultA = Result<int, string>.Ok(42);
var resultB = Result<string, string>.Err("Error Message");
var andResult = resultA.And(resultB); // Err("Error Message")
var orResult = resultA.Or(resultB); // Ok(42)
First Result is an Error (Err), Second Result is Successful (Ok):
var resultA = Result<int, string>.Err("Error Message");
var resultB = Result<string, string>.Ok("Success");
var andResult = resultA.And(resultB); // Err("Error Message")
var orResult = resultA.Or(resultB); // Ok("Success")
Both Results are Errors (Err):
var resultA = Result<int, string>.Err("Error 1");
var resultB = Result<string, string>.Err("Error 2");
var andResult = resultA.And(resultB); // Err("Error 1")
var orResult = resultA.Or(resultB); // Err("Error 2")
Inspectors
Inspect(Action<T> inspector)
: Invokes an action on the value of the successful result.InspectError(Action<E> inspector)
: Invokes an action on the error value or message of the error result.
Examples of Inspectors
// Inspect: Invokes an action on the value of the successful result if it's successful.
var result = Result<int, string>.Ok(42);
result.Inspect(value => Console.WriteLine($"Value is {value}"));
// Prints: Value is 42
// InspectError: Invokes an action on the error value or message if the result is an error.
result = Result<int, string>.Err("Error Message");
result.InspectError(error => Console.WriteLine($"Error occurred: {error}"));
// Prints: Error occurred: Error Message
Unwrappers
Expect(string message)
: Expects a successful result and returns its value; otherwise, throws an exception with the specified message.Unwrap()
: Returns the value of the successful result or throws an exception.UnwrapOr(T defaultValue)
: Returns the value of the successful result or adefaultValue
.UnwrapOrDefault()
: Returns the value of the successful result or default value for the type.UnwrapUnchecked()
: Returns the value of the successful result or throws an exception.ExpectError(string message)
: Expects an error result and returns its error value; otherwise, throws an exception with the specified message.UnwrapError()
: Returns the error value of the error result or throws an exception.UnwrapErrorUnchecked()
: Returns the error value of the error result or throws an exception.
Examples of Unwrappers
// Methods for Successful Results
var resultOk = Result<int, string>.Ok(42);
var resultErr = Result<int, string>.Err("Error Message");
// Expect - Expects a successful result and returns its value
var valueOk = resultOk.Expect("Value was expected but not present"); // Returns 42
var valueErr = resultErr.Expect("Value was expected but not present"); // Throws an exception: "Value was expected but not present: Error Message"
// Unwrap - Returns the value of the successful result
// Throws an exception: "Error Message"
valueOk = resultOk.Unwrap(); // Returns 42
valueErr = resultErr.Unwrap(); // Throws an exception: "Error Message"
// UnwrapOrDefault - Returns the value of the successful result or default value for the type
valueOk = resultOk.UnwrapOrDefault(); // Returns 42
valueErr = resultErr.UnwrapOrDefault(); // Returns 0
// UnwrapUnchecked - Returns the value of the successful result or throws an exception
// Throws an UndefinedBehaviorException: "Undefined behavior for this result : {result}"
valueOk = resultOk.UnwrapUnchecked(); // Returns 42
valueErr = resultErr.UnwrapUnchecked(); // Throws an UndefinedBehaviorException: "Undefined behavior for this result : 42"
// Methods for Error Results
// ExpectError - Expects an error result and returns its error value
valueOk = resultOk.ExpectError("Error was expected but not present"); // Returns "Error was expected but not present: 42"
valueErr = resultErr.ExpectError("Error was expected"); // Returns "Error was expected: Error Message"
// UnwrapError - Returns the error value of the error result or throws an exception
// Throws an UnwrapException: "The value {value} could not be unwrapped: {message}"
valueOk = result.UnwrapError(); // Throws an UnwrapException: "The value "Error Message" could not be unwrapped: The result is not an error."
valueErr = result.UnwrapError(); // Returns "Error Message"
// UnwrapErrorUnchecked - Returns the error value of the error result or throws an exception
// Throws an UndefinedBehaviorException: "Undefined behavior for this result: {result}"
valueOk = resultOk.UnwrapErrorUnchecked(); // Throws an UndefinedBehaviorException: "Undefined behavior for this result: 42"
valueErr = resultErr.UnwrapErrorUnchecked(); // Returns "Error Message"
Functional Programming Features
Extensors Logic Operators
AndThen<U>(Func<T, Result<U, E>> function)
: Calls function if the result is successful; otherwise returns a new instance representing this error result.OrElse<F>(Func<E, Result<T, F>> function)
: Calls function if the result is NOT successful; otherwise returns a new instance representing this ok result.
Extensors Mappers & Flattens
Mappers
Map<U>(Func<T, U> mapper)
: Maps the successful result value to a new value of a different type.MapError<F>(Func<E, F> mapper)
: Maps the error value or message to a new value of a different type.MapOr<U>(Func<T, U> mapper, U defaultValue)
: Maps the successful result value to a new value or returns adefaultValue
.MapOrElse<U>(Func<T, U> mapper, Func<E, U> function)
: Maps the successful result or returns a value based on the error object.
Flattens
Result<T, E> Flatten<T, E>(this Result<Result<T, E>, E> result)
: Flattens a nested result by extracting the inner result, discarding the error value of the outer result.
How mapping results
// Map: Map<U>(Func<T, U> mapper)
var result = Result<int, string>.Ok(42);
var mappedResult = result.Map(value => $"The answer is {value}");
// mappedResult is now Result<string, string>.Ok("The answer is 42")
// MapError: MapError<F>(Func<E, F> mapper)
result = Result<int, string>.Err("Error Message");
mappedResult = result.MapError(error => $"An error occurred: {error}");
// mappedResult is now Result<int, string>.Err("An error occurred: Error Message")
// MapOr: MapOr<U>(Func<T, U> mapper, U defaultValue)
result = Result<int, string>.Ok(42);
var mappedValueFromOk = result.MapOr(value => value * 2, defaultValue: 0);
// mappedValue is now 84
// MapOr: MapOr<U>(Func<T, U> mapper, U defaultValue)
result = Result<int, string>.Error("Error Message");
var mappedValueFromErr = result.MapOr(value => value * 2, defaultValue: 0);
// mappedValue is now 0
// MapOrElse: MapOrElse<U>(Func<T, U> mapper, Func<E, U> function)
result = Result<int, string>.Ok(42);
mappedValueFromErr = result.MapOrElse(value => value * 2, error => error.Length);
// mappedValue is now 84
// MapOrElse: MapOrElse<U>(Func<T, U> mapper, Func<E, U> function)
result = Result<int, string>.Err("Error Message");
mappedValueFromErr = result.MapOrElse(value => value * 2, error => error.Length);
// mappedValue is the length of the error message, which is 13
How Flattening results
// Creating a nested result
var nestedOkResult = Result<Result<int, string>, string>.Ok(Result<int, string>.Ok(42));
var nestedResult = Result<Result<int, string>, string>.Ok(Result<int, string>.Err("Error Message"));
var nestedErrResult = Result<Result<int, string>, string>.Err("Error Message");
// Flattening the nested result to get the inner result
var flattenedResult = nestedOkResult.Flatten(); // Ok(42)
flattenedResult = nestedResult.Flatten(); // Error("Error Message")
flattenedResult = nestedErrResult.Flatten(); // Error("Error Message")
Extensors Unwrappersl
UnwrapOrElse(Func<E, T> function)
: Returns the value of the successful result or a value based on the error object.
Examples of Unwrappers
// UnwrapOrElse - Returns the value of the successful result or a value based on the error object
valueOk = resultOk.UnwrapOrElse(error => error.Length); // Returns 42
valueErr = resultErr.UnwrapOrElse(error => error.Length); // Returns 13 (length of the error message)
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net7.0 is compatible. 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. |
-
net7.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.
first release