Maybe inspired by this article
Maybe is implemented as readonly struct. Maybe is empty when its holded value is null.
//new empty
var maybe = new Maybe<User>();
var maybe = default(Maybe<User>);
//from object
var maybe = userObject.ToMaybe();
var maybe = new Maybe<User>(userObject);
//implicit cast
Maybe<object> may = new object();
Maybe<int> maybe = 1;
void Method(Maybe<int> arg) {...}
Method(10);
Bind method performs an action on the value when maybe contains one.
Maybe<Stream> stream = ...
//Func<T,TResult>
Maybe<int> readByte = stream.Bind(s => s.ReadByte());
//Func<T,Task<TResult>>
Maybe<int> readByte = await stream.Bind(s => s.ReadAsync(...));
//Action<T>
stream.Bind(s => s.Flush());
OrElse method is opposite to Bind. It performs the action when maybe is empty.
Maybe<User> user = ...
//Func<T>
User instance = user.OrElse(() => new User());
//Func<Task<T>>
User instance = await user.OrElse(() => database.Get(...));;
//Value
User instance = user.OrElse(anonymousUserInstance);
User instance = user.OrDefault();
Match accepts both bind and orElse actions as parameters.
Maybe<Order> order = ...
//Action<T>
order.Match(o => o.Accept(payment), () => Refund(payment, "Order not found."))
//Func<T, TResult>
Order instance = order.Match(o => o.AddLineItem(newItem), () => new Order(newItem));
Maybe implements IEnumerable<T>, IEquatable<Maybe<T>>, IEquatable<T>
Maybe<User> maybe = ...
bool hasValue = maybe.Any();
//Single returns value or throws InvalidOperationException
User instance = maybe.Single();
//TryGet returns flag and value
bool hasValue = maybe.TryGet(var out value);
//Throw exception when maybe contains value.
maybe.BindThrow(() => new Exception());
//Throw exception when maybe is empty
User instance = maybe.OrThrow(() => new NotFoundException());
//Dictionary extensions
IReadOnlyDictionary<string, string> dictionary = ...
Maybe<string> value = dictionary.GetValue(key);
//Cast
Maybe<Administrator> admin = maybe.As<Administrator>();
//Empty string
Maybe<string> stringValue = " ".ToMaybe(emptyAsNull: true);
System.Text.Json serialization supported.