Last active
July 21, 2023 08:28
-
-
Save kekyo/68bfa6a23b26b1a7ff2a1077525ba4d4 to your computer and use it in GitHub Desktop.
Hacked Option<T> enabling pattern matching on C#
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
// Copyright (c) Kouji Matsui (@[email protected]) | |
// License under MIT. | |
using System.ComponentModel; | |
namespace TestApp; | |
public static class Option | |
{ | |
public static readonly NoneOption None = | |
NoneOption.Value; | |
public static Option<T> Some<T>(T value) => | |
new SomeOption<T>(value); | |
} | |
[EditorBrowsable(EditorBrowsableState.Never)] | |
public sealed class NoneOption : None | |
{ | |
private NoneOption() | |
{ | |
} | |
public override string ToString() => | |
"None"; | |
public static readonly NoneOption Value = | |
new NoneOption(); | |
} | |
public abstract class Option<T> | |
{ | |
public static implicit operator Option<T>(NoneOption none) => | |
NoneOption<T>.Value; | |
} | |
public interface Some | |
{ | |
void Deconstruct(out object? value); | |
} | |
public interface Some<T> | |
{ | |
void Deconstruct(out T value); | |
} | |
public interface None | |
{ | |
} | |
internal sealed class SomeOption<T> : Option<T>, Some<T>, Some | |
{ | |
private readonly T value; | |
public SomeOption(T value) => | |
this.value = value; | |
void Some.Deconstruct(out object? value) => | |
value = this.value; | |
void Some<T>.Deconstruct(out T value) => | |
value = this.value; | |
public override string ToString() => | |
$"Some {(this.value is string str ? $"\"{str}\"" : this.value?.ToString() ?? "(null)")}"; | |
} | |
internal sealed class NoneOption<T> : Option<T>, None | |
{ | |
public NoneOption() | |
{ | |
} | |
public override string ToString() => | |
"None"; | |
public static readonly Option<T> Value = | |
new NoneOption<T>(); | |
} | |
// ===================================================================== | |
public static Option<string> FooBar() | |
{ | |
return Option.Some("ABC"); | |
return Option.None; | |
} | |
switch (FooBar()) | |
{ | |
case Some(var str): | |
// ... | |
break; | |
case None: | |
// ... | |
break; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment