使用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);}}