Crank.Result 1.2.0

dotnet add package Crank.Result --version 1.2.0
                    
NuGet\Install-Package Crank.Result -Version 1.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Crank.Result" Version="1.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Crank.Result" Version="1.2.0" />
                    
Directory.Packages.props
<PackageReference Include="Crank.Result" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Crank.Result --version 1.2.0
                    
#r "nuget: Crank.Result, 1.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Crank.Result@1.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Crank.Result&version=1.2.0
                    
Install as a Cake Addin
#tool nuget:?package=Crank.Result&version=1.2.0
                    
Install as a Cake Tool

Crank.Result

Crank result are a set of slightly opinionated result classes.

Result

  • Contains a Succeeded, Failed and an optional Message value.
  • Failed == !Succeeded

Setting the result:

Assignment:

Result result = true;

Tuple Assignment:

Result result = (true, "Success message"); Result result = (false, "Failure message");

Static Methods:

Result result = Result.Success(); Result result = Result.Fail(); Result result = Result.Fail("Failure message");

Result< int> result = Result.Fail< int>(404, "Failure message"); // note: fails up to Result< TPrimaryValue> from Result

Checking success:

If (result == true) ... If (result.Succeeded) ... If (!result.Failed) ...

Extracting values:

var errorMessage = result.Message; var (succeeded, message) = result;

// Return false and default as Result has no value bool haveValue = result.TryGetValue<int>(out int? value); int? value = result.As<int>();

Result< TPrimaryValue >

  • inherits from Result
  • TPrimaryValue is accessible from the Value member
  • opinionated: when directly assigning a TPrimaryValue value, infers success == true

Setting the result:

Assignment:

Result< Guid> result = Guid.NewGuid();
// side effect: set Succeeded to true

Tuple Assignment:

Result< Guid> result = (succeeded, Guid.NewGuid()); Result< Guid> result = (succeeded, Guid.NewGuid(), "Error Message");

Static Methods:

Result< Guid> result = Result< Guid>.Success(Guid.NewGuid()); Result< Guid> result = Result< Guid>.Fail(value: Guid.NewGuid(), message: "Error message");

Result< Guid, int> result = Result.Fail< int>(404, "Failure message"); // note: fails up to Result<TPrimaryResult, TSecondaryResult> from Result< TPrimaryResult>

Checking success:

If (result == true) ... If (result.Succeeded) ... If (!result.Failed) ...

Extracting values:

Guid id = result.Value; Guid id = result; var (succeeded, guidValue) = result; var (succeeded, guidValue, message) = result;

bool haveValue = result.TryGetValue< Guid>(out Guid? value); Guid? value = result.As< Guid>();

[v1.2] Deref

deconstruct reference type without nullable inference var (succeeded, value, message) = result.Deref(); notes: if value is null, succeeded will be destructed as false equivant of: succeeded = (succeeded && value != null) can change this behaviour by calling Deref(false)

Result< TPrimaryValue, TSecondaryValue >

  • inherits from Result< TPrimaryValue>
  • Assignable to TResult< TPrimaryValue> where both TPrimaryValues are the same type -- opinionated: TSecondaryValue is accessible from the Value member (instead of TPrimaryValue) -- opinionated: when directly assigning a TSecondaryValue value, infers success == false

Setting the result:

Assignment:

Result< Guid, int> result = 404; // side effect: set Succeeded to false

Tuple Assignment:

Result< Guid, int> result = (404, "Failure message"); Result< Guid, int> result = (succeeded, 404, "Failure message");

Static Methods:

Result< Guid, int>.Fail(value: Guid.NewGuid(), message: "Error message");

Checking success:

If (result == true) ... If (result.Succeeded) ... If (!result.Failed) ...

Extracting Values

int errorCode = result.Value; int errorCode = result; var (succeeded, intValue) = result; var (succeeded, intValue, message) = result;

bool haveValue = result.TryGetValue< int>(out int? value); int? value = result.As< int>();

[v1.2] Deref

deconstruct reference type without nullable inference var (succeeded, value, message) = result.Deref();

Setting and extracting both values

Result<Guid, int> result = (true, Guid.NewGuid(), 200, "Success Message"); (succeeded, primaryValue, secondaryValue) = result; (succeeded, primaryValue, secondaryValue, message) = result;

Common usage examples

Returning a result with an error message

public Result InvokeOperation()
{
	try
	{
		_repository.Invoke();
		return true;
	}
	catch (Exception ex)
	{
		return (false, ex.Message);
	}
} 

Returning success or additional error data

public Result InvokeOperation
{
	try
	{
		int resultCode = _repository.Invoke();
		if (resultCode > 0)
			return true;

		// fail up to Result<TPrimary>
		return Result.Fail(resultCode);
	}
	catch (Exception ex)
	{
		// fail up to Result<TPrimary>
		return Result.Fail(ex);
	}
}

Return success data or failure

public Result<IEnumerable<RowData>> LoadRowData(string filename)
{
	try
	{
		var data = _repository.LoadData(filename);
		return data;
	}
	catch (Exception ex)
	{
		// fail up to Result<TPrimary, TSecondary>
		return Result<IEnumerable<RowData>>.Fail(ex);
	}
}

Differentiating between different result types

var result = LoadRowData();
if (result.Succeeded) // happy case
	return Ok(result.Value);

if (result is Result<IEnumerable<RowData>, int> errorResult)
	return ErrorResult(new { errorCode = errorResult.Value });

if (result is Result<IEnumerable<RowData>, Exception> exceptionResult)
	return InternalServerError();

...	alterative

var result = LoadRowData();
if (result.Succeeded) ...

if (result.TryGetValue<int>(out int errorCode))
	return ErrorResult(new { errorCode });

if (result.TryGetValue<Exception>(out Exception _))
	return InternalServerError();

Change Logs

[1.0] Initial release

[1.1] Added NotNull property and tests

[1.2] Removed NotNull property and tests Added Deref Result extensions methods and tests

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  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 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 was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net6.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.

Version Downloads Last Updated
1.2.0 195 2/17/2025
1.1.0 155 2/12/2025
1.0.0 148 1/19/2025