Skip to content

Instantly share code, notes, and snippets.

@roobie
Created March 18, 2021 23:25
Show Gist options
  • Save roobie/cfd94f33f8e7cc62ea097f2f9f55a21c to your computer and use it in GitHub Desktop.
Save roobie/cfd94f33f8e7cc62ea097f2f9f55a21c to your computer and use it in GitHub Desktop.
.NET Option type re-using LINQ
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
}
}
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