Created
March 18, 2021 23:25
-
-
Save roobie/cfd94f33f8e7cc62ea097f2f9f55a21c to your computer and use it in GitHub Desktop.
.NET Option type re-using LINQ
This file contains 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; | |
using System.Collections; | |
using System.Collections.Generic; | |
#nullable enable | |
namespace Option | |
{ | |
public abstract class Option<T> : IEnumerable<T>, IEquatable<T> | |
{ | |
protected T[] Value { get; set; } = new T[] {}; | |
public static Option<T> Some(T value) | |
{ | |
if (value == null) | |
{ | |
throw new ArgumentNullException(nameof(value)); | |
} | |
return new _Some(value); | |
} | |
public static readonly Option<T> None = new _None(); | |
private class _Some:Option<T> | |
{ | |
internal _Some(T value) | |
{ | |
this.Value = new T[] { value }; | |
} | |
public override string ToString() | |
{ | |
return $"Some({this.Value})"; | |
} | |
} | |
private class _None : Option<T> | |
{ | |
public _None() | |
{ | |
// this.Value = new T[] {}; | |
} | |
public override string ToString() | |
{ | |
return "None"; | |
} | |
} | |
// Begin: IEquatable<T> implementation | |
public bool Equals(T? other) | |
{ | |
if (this is _Some) | |
{ | |
var value = this.Value[0]; | |
if (value != null) | |
{ | |
return value.Equals(other); | |
} | |
throw new Exception("Invariant failed! The Some type cannot hold a null."); | |
} | |
return (this is _None) && (other == null); | |
} | |
// End: IEquatable<T> implementation | |
// Begin: IEnumerable<T> implementation | |
public IEnumerator<T> GetEnumerator() | |
{ | |
foreach (var item in Value) | |
{ | |
yield return item; | |
} | |
} | |
IEnumerator IEnumerable.GetEnumerator() | |
{ | |
return this.GetEnumerator(); | |
} | |
// End: IEnumerable<T> implementation | |
} | |
} |
This file contains 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 Option.Abstractions | |
{ | |
public static class OptAbstractions | |
{ | |
public static Option<T> ToOption<T>(this T value) | |
where T: class | |
{ | |
if (value == null) | |
{ | |
return Option<T>.None; | |
} | |
return Option<T>.Some(value); | |
} | |
public static Option<T> AsOption<T>(this Nullable<T> value) | |
where T : struct | |
{ | |
if (!value.HasValue) | |
{ | |
return Option<T>.None; | |
} | |
return Option<T>.Some(value.Value); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment