using System; using System.Collections.Generic; namespace ICD.Common.Utils { /// /// Convenience wrapper for supporting null keys in hash tables. /// /// public struct NullObject : IEquatable>, IComparable> { #region Properties public T Item { get; private set; } public bool IsNull { get; private set; } public static NullObject Null { get { return new NullObject(); } } #endregion #region Constructors /// /// Constructor. /// /// public NullObject(T item) // ReSharper disable CompareNonConstrainedGenericWithNull : this(item, item == null) // ReSharper restore CompareNonConstrainedGenericWithNull { } /// /// Constructor. /// /// /// private NullObject(T item, bool isnull) : this() { IsNull = isnull; Item = item; } #endregion public override string ToString() { // ReSharper disable CompareNonConstrainedGenericWithNull return Item == null ? "NULL" : Item.ToString(); // ReSharper restore CompareNonConstrainedGenericWithNull } #region Casting public static implicit operator T(NullObject nullObject) { return nullObject.Item; } public static implicit operator NullObject(T item) { return new NullObject(item); } #endregion #region Equality public override bool Equals(object obj) { if (obj == null) return IsNull; if (!(obj is NullObject)) return false; return Equals((NullObject)obj); } public bool Equals(NullObject other) { if (IsNull) return other.IsNull; return !other.IsNull && Item.Equals(other.Item); } public override int GetHashCode() { if (IsNull) return 0; var result = Item.GetHashCode(); if (result >= 0) result++; return result; } #endregion #region Comparable public int CompareTo(NullObject other) { if (IsNull && other.IsNull) return 0; if (IsNull) return -1; return Comparer.Default.Compare(Item, other.Item); } #endregion } }