解决空值的策略
使用Option<T>类型二不是null是解决空值问题的另一种策略。与null相比,Option<T>类型是一个更安全的方法,因为它同样适用于值类型和引用类型。而且它的功能更强大,因为它用“元数据”的方法保存一个值的额外信息,因此允许我们使用某个类型的整个值域,包括null本身。以下是完整代码。
public sealed class Option { private Option() { } public static Option<T> Some<T>(T value) { return new Option<T>(value); } public static readonly Option None = new Option(); } public static class OptionHelpers { public static Option<T> ToOption<T>(this T val) { return Option.Some(val); } public static Option<T> ToNotNullOption<T>(this T val) where T : class { return val != null ? val.ToOption() : Option.None; } } public sealed class Option<T> { private readonly T value; public T Value { get { return value; } } private readonly bool hasValue; public bool HasValue { get { return hasValue; } } public bool IsSome { get { return hasValue; } } public bool IsNone { get { return !hasValue; } } public Option(T value) { this.value = value; this.hasValue = true; } private Option() { } private static readonly Option<T> None = new Option<T>(); public static bool operator ==(Option<T> a, Option<T> b) { return a.HasValue == b.HasValue && EqualityComparer<T>.Default.Equals(a.Value, b.Value); } public static bool operator !=(Option<T> a, Option<T> b) { return !(a == b); } public static implicit operator Option<T>(Option option) { return None; } public override int GetHashCode() { int hashCode = hasValue.GetHashCode(); if (hasValue) hashCode ^= value.GetHashCode(); return hashCode; } public override bool Equals(object obj) { return base.Equals(obj); } public Option<R> Bind<R>(Func<T, Option<R>> g) { if (IsNone) return Option.None; return g(Value); } }