Created
May 9, 2021 11:48
-
-
Save MrModest/b97fb9572b21dba859c1a5312581444a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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