解决空值的策略

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

 

posted @ 2015-04-14 16:52  荣码一生  阅读(162)  评论(0编辑  收藏  举报