Skip to content

Instantly share code, notes, and snippets.

@MrModest
Created May 9, 2021 11:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MrModest/b97fb9572b21dba859c1a5312581444a to your computer and use it in GitHub Desktop.
Save MrModest/b97fb9572b21dba859c1a5312581444a to your computer and use it in GitHub Desktop.
using System;
namespace YourDomenName
{
public readonly struct Optional<TValue> where TValue : notnull
{
private readonly TValue? _value;
public static Optional<TValue> None { get; } = new (default, false);
public bool HasValue { get; }
public TValue Value
{
get
{
if (HasValue)
return _value!;
throw new InvalidOperationException($"Value for Optional<{typeof(TValue).FullName}> is not present!");
}
}
private Optional(TValue? value, bool hasValue)
{
if (hasValue && value == null)
{
throw new ArgumentNullException(nameof(value));
}
_value = value;
HasValue = hasValue;
}
public Optional(TValue value)
: this(value, true)
{
}
public override bool Equals(object? otherObj)
{
if (otherObj is Optional<TValue> other)
return Equals(other);
return false;
}
public override int GetHashCode()
{
return !HasValue
? base.GetHashCode()
: Value.GetHashCode();
}
public bool Equals(Optional<TValue> other)
{
if (HasValue && other.HasValue)
{
return Value.Equals(other.Value);
}
return HasValue == other.HasValue;
}
public override string ToString()
{
return HasValue
? $"Optional[{Value}]"
: "Optional.None";
}
}
public static class Optional
{
public static Optional<TValue> AsOptional<TValue>(this TValue value)
where TValue : notnull
{
return new(value);
}
public static Optional<TValue> Of<TValue>(TValue value)
where TValue: notnull
{
return new(value);
}
public static Optional<TValue> OfNullable<TValue>(TValue? value)
where TValue: notnull
{
return value != null
? new Optional<TValue>(value)
: Optional<TValue>.None;
}
public static Optional<TValue> None<TValue>()
where TValue: notnull
{
return Optional<TValue>.None;
}
public static Optional<TValue> Or<TValue>(this Optional<TValue> optional, Func<Optional<TValue>> getter)
where TValue: notnull
{
return optional.HasValue
? optional
: getter();
}
public static TValue OrValue<TValue>(this Optional<TValue> optional, Func<TValue> getter)
where TValue: notnull
{
return optional.HasValue
? optional.Value
: getter();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment