// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Globalization; using System.Reflection; using System.Collections.Generic; using System.Runtime; using System.Runtime.CompilerServices; using System.Security; using System.Diagnostics.Contracts; namespace System { // Warning, don't put System.Runtime.Serialization.On*Serializ*Attribute // on this class without first fixing ObjectClone::InvokeVtsCallbacks // Also, because we have special type system support that says a a boxed Nullable // can be used where a boxed is use, Nullable can not implement any intefaces // at all (since T may not). Do NOT add any interfaces to Nullable! // [Serializable] [System.Runtime.Versioning.NonVersionable] // This only applies to field layout public struct Nullable where T : struct { private bool hasValue; internal T value; [System.Runtime.Versioning.NonVersionable] public Nullable(T value) { this.value = value; hasValue = true; } public bool HasValue { [System.Runtime.Versioning.NonVersionable] get { return hasValue; } } public T Value { get { if (!hasValue) { ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NoValue); } return value; } } [System.Runtime.Versioning.NonVersionable] public T GetValueOrDefault() { return value; } [System.Runtime.Versioning.NonVersionable] public T GetValueOrDefault(T defaultValue) { return hasValue ? value : defaultValue; } public override bool Equals(object other) { if (!hasValue) return other == null; if (other == null) return false; return value.Equals(other); } public override int GetHashCode() { return hasValue ? value.GetHashCode() : 0; } public override string ToString() { return hasValue ? value.ToString() : ""; } [System.Runtime.Versioning.NonVersionable] public static implicit operator Nullable(T value) { return new Nullable(value); } [System.Runtime.Versioning.NonVersionable] public static explicit operator T(Nullable value) { return value.Value; } // The following already obsoleted methods were removed: // public int CompareTo(object other) // public int CompareTo(Nullable other) // public bool Equals(Nullable other) // public static Nullable FromObject(object value) // public object ToObject() // public string ToString(string format) // public string ToString(IFormatProvider provider) // public string ToString(string format, IFormatProvider provider) // The following newly obsoleted methods were removed: // string IFormattable.ToString(string format, IFormatProvider provider) // int IComparable.CompareTo(object other) // int IComparable>.CompareTo(Nullable other) // bool IEquatable>.Equals(Nullable other) } public static class Nullable { public static int Compare(Nullable n1, Nullable n2) where T : struct { if (n1.HasValue) { if (n2.HasValue) return Comparer.Default.Compare(n1.value, n2.value); return 1; } if (n2.HasValue) return -1; return 0; } public static bool Equals(Nullable n1, Nullable n2) where T : struct { if (n1.HasValue) { if (n2.HasValue) return EqualityComparer.Default.Equals(n1.value, n2.value); return false; } if (n2.HasValue) return false; return true; } // If the type provided is not a Nullable Type, return null. // Otherwise, returns the underlying type of the Nullable type public static Type GetUnderlyingType(Type nullableType) { if ((object)nullableType == null) { throw new ArgumentNullException(nameof(nullableType)); } Contract.EndContractBlock(); Type result = null; if (nullableType.IsGenericType && !nullableType.IsGenericTypeDefinition) { // instantiated generic type only Type genericType = nullableType.GetGenericTypeDefinition(); if (Object.ReferenceEquals(genericType, typeof(Nullable<>))) { result = nullableType.GetGenericArguments()[0]; } } return result; } // The following already obsoleted methods were removed: // public static bool HasValue(Nullable value) // public static T GetValueOrDefault(Nullable value) // public static T GetValueOrDefault(Nullable value, T valueWhenNull) // The following newly obsoleted methods were removed: // public static Nullable FromObject(object value) // public static object ToObject(Nullable value) // public static object Wrap(object value, Type type) // public static object Unwrap(object value) } }