Open gaufung opened 2 days ago
Option Monad
是一种编程范式,它可以解决编程中 Null
问题,在 C#
中我们可以使用 nullable
类型来解决这个问题,但是 Option Monad
已经广泛使用在其他编程语言中。
首先我们定义个 Mayb<T>
的类型
public abstract class Maybe<T>
{
private Maybe()
{
}
public static Maybe<T> None => new NULL();
private sealed class NULL : Maybe<T>
{
}
public sealed class Some : Maybe<T>
{
public Some(T value) => Value = value;
public T Value { get; }
}
public bool TryGetValue(out T value)
{
if (this is Some some)
{
value = some.Value;
return true;
}
else
{
value = default(T);
return false;
}
}
public TResult Match<TResult>(Func<T, TResult> some, Func<TResult> none)
{
if (this is Some s)
{
return some(s.Value);
}
else
{
return none();
}
}
public void Match(Action<T> some, Action none)
{
if (this is Some s)
{
some(s.Value);
}
else
{
none();
}
}
}
这里 Maybe<T>
是一个抽象类型,而 Some<T>
和 Null<T>
是两个具体的子类,而且定义 None
的静态属性为 Null<T>
的具体实现。除此之外,还定义了 TryGetValue
和 Match
两个方法方便使用。
这样我们的方法定义的返回值如下
Maybe<string> GetLogContent(int id)
{
var filename = $"log{id}.txt";
if (File.Exists(filename))
{
return new Maybe<string>.Some(File.ReadAllText(filename));
}
else
{
return Maybe<string>.None;
}
}
那么使用的使用有很多方法
var content = GetLogContent(1);
// Type Cast
if (content is Maybe<string>.Some some)
{
Console.WriteLine(some.Value);
}
else
{
Console.WriteLine("No content found");
}
// TryGetValue
if (content.TryGetValue(out var value))
{
Console.WriteLine(value);
}
else
{
Console.WriteLine("No content found");
}
// Match
content.Match(
some: value => Console.WriteLine(value),
none: () => Console.WriteLine("No content found")
);
https://www.youtube.com/watch?v=Phn2Mu8zoxM&ab_channel=MilanJovanovi%C4%87