Power enums lets you have Some and None in C# as a representation of optional types. This is like Rust's Option enum type which I think it's brilliant.
First, install NuGet. Then, install PowerEnums from the package manager console:
PM> Install-Package PowerEnums
Or from the .NET CLI as:
dotnet add package PowerEnums
The library supports .NET Core 3.1 and above. Install the NUGET package as directed above, then you can use it like below:
Simple Option - Some
int value = 50;
var option = new Some<int>(value);
Console.WriteLine(option?.ValueOrDefault());
Assert.Equal(value, option?.ValueOrDefault());
Assert.NotNull(option);
Assert.IsType<Some<int>>(option);
Assert.IsType<int>(option?.ValueOrDefault());
Simple Option - None
var noneReturningOption = new None<int>();
Assert.NotNull(noneReturningOption);
Assert.Equal(0, noneReturningOption?.ValueOrDefault());
Assert.Equal(0, noneReturningOption?.Value);
Assert.Equal(false, noneReturningOption?.IsSome());
Assert.Equal(true, noneReturningOption?.IsNone());
Assert.IsType<None<int>>(noneReturningOption);
//it doesn't lose it's enclosed primitive type though it still came as None
Assert.IsType<int>(noneReturningOption?.ValueOrDefault());
Assert.IsAssignableFrom<int>(noneReturningOption?.ValueOrDefault());
Option-returning methods Option
private static Option<decimal> DecimalReturningOptionMethod()
{
decimal d = decimal.MaxValue;
return new Some<decimal>(d);
}
private Option<Person> GetPerson_Some_Or_None()
{
var person = new Person { Name = "Willelm Rudenmalm", Age = 28 };
return new Some<Person>(person) ?? new None<Person>();
}
Option().ValueOrError() with error message
var option = new None<int>();
Assert.Throws<Exception>(() => option.ValueOrError("Error could not retrieve item , item is null or default"));
Option().ValueOrError() with error callback
var option = new None<int>();
Assert.Throws<MyCustomException>(() => option.ValueOrError(() => throw new MyCustomException("Error could not find item")));
Check IsSome() or IsNone()
var option = new Some<double>(2.58);
if(option.IsSome()){
Console.WriteLine($"Option is Some and it's value is {option.ValueOrDefault()}");
//OR destroy everything.
//without saying, this throws a bomb (an Exception) if option is None<T>
var valueOrMakeAMess = option.ValueOrError("This double is supposed to be here now I'm going to have to throw an exception");
//OR pass an Exception callback with your own customer Exception
//without saying, this throws a bomb (a YourMessyCustomException) if option is None<T>
var valueOrMakeAMess = option.ValueOrError(() => throw new YourMessyCustomException("You must never not have this double"));
}else{
Console.WriteLine("Option is None");
}