A very simple implementation of the optional pattern with a few extension methods.
// Explicitly
var optional = Optional<int>.Of(123);
// Implicitly
Optional<int> optional = 123;
// Extension method
var optional = 123.AsOptional();
// From Task/ValueTask
var optional = Task.FromResult(123).AsOptionalAsync();
var optional = new ValueTask(123).AsOptionalAsync();
// None
var none = Optional<int>.None();
var value = Optional<int>.Of(123).ValueOr(321);
var convertOptional = Optional<int>.Of(123).Convert(x => (long)x);
var convertValue = Optional<int>.Of(123).ConvertOr(x => (long)x, 321L);
Both synchronous (void) and asynchronous (Task and ValueTask) can be invoked.
Optional<int>.Of(123)
.IfHasValue(x => { /* do something with the value */ })
.OrElse(() => { /* do something if no value */ });
await Optional<int>.None()
.IfHasValueAsync(x => new ValueTask())
.OrElseAsync(() => new ValueTask());
FirstOrOptional
var items = new [] { 1, 2, 3 };
var item = items.FirstOrOptional();
var item = items.FirstOrOptional(x => x % 2 == 0);
LastOrOptional
var items = new [] { 1, 2, 3 };
var item = items.LastOrOptional();
var item = items.LastOrOptional(x => x % 2 == 0);
SingleOrOptional
var items = new [] { 1, 2, 3 };
var item = items.SingleOrOptional();
var item = items.SingleOrOptional(x => x % 2 == 0);
ElementAtOrOptional
var items = new [] { 1, 2, 3 };
var item = items.SingleOrOptional(3);
MinOrOptional
var items = new [] { 1, 2, 3 };
var item = items.MinOrOptional();
var items = new []
{
new { Number = "1" },
new { Number = "2" }
};
var item = items.MinOrOptional(x => x.Number);
MaxOrOptional
var items = new [] { 1, 2, 3 };
var item = items.MaxOrOptional();
var items = new []
{
new { Number = "1" },
new { Number = "2" }
};
var item = items.MaxOrOptional(x => x.Number);