A simple and easy to use option type for C#.
SimpleOption is a strongly typed alternative to null that helps to avoid null-reference exceptions, model your data more explictly and cut down on manual null checks.
SimpleOption is available via NuGet package manager:
PM> Install-Package Alterius.SimpleOption
Or via .NET CLI:
> dotnet add package Alterius.SimpleOption
Or visit https://www.nuget.org/packages/Alterius.SimpleOption
To use SimpleOption reference Alterius.SimpleOption.dll
and import the following namespace:
using Alterius.SimpleOption;
Using static constructors:
var none = Option.None<string>();
var noneWithException = Option.None<string>(new Exception());
var some = Option.Some("Something");
Using implicit casting:
Option<string> option;
option = (string)null;
option = new Exception();
option = "Something";
Using Option<T>
as a method return type:
public Option<string> GetString(object obj)
{
if (obj == null)
{
return new ArgumentNullException(nameof(obj));
}
var str = _someRepo.GetString(obj);
if (str == null)
{
return Option.None<string>();
}
return str;
}
Retrieving values is achieved by using the Match()
method and its various overloads.
A basic example:
int x = option.Match(
some => some + 1,
() => -1);
A good use of Option<T>
is when retuning an IActionResult
in a WebApi controller:
return option.Match<IActionResult>(
some => Ok(some),
() => NotFound());
Please note that in this example
TResult
is declared explicitly asOk()
andNotFound()
do not return the same type, even though they both return an implementation ofIActionResult
. This is not necessary under normal circumstances when the return types are identical.
Passing an instance of an exception to Option<T>
allows you to handle application faults without the cost of throwing the exception:
return option.Match<IActionResult>(
some => Ok(some),
e => {
if (e is NotFoundException) return NotFound();
return BadRequest();
});
Warning! Accessing the value of the exception
(e)
can result in aNullReferenceException
if there is no exception passed to the option and the result of the exceptionMatch()
is none.
Using Option<T>
as a method parameter:
public bool HasString(Option<object> obj)
{
return obj.Match(
some => string.IsNullOrEmpty(some.ToString()),
() => false);
}
A fluent interface is available as an alternative to the Match()
method in version 1.0.0.1 and upwards:
int x = option
.Some(some => some + 1)
.None(() => -1);
return option
.Some<IActionResult>(some => Ok(some))
.None(() => NotFound());
return option
.Some(some => Ok(some))
.None(e => {
if (e is NotFoundException) return NotFound();
return BadRequest();
});
It's not recommended to mix the fluent interface with the
Match()
method as it'll probably get confusing. Pick one style and stick with it.