1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
using System;
namespace 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;
// 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<T>
// can be used where a boxed<T> is use, Nullable<T> 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<T> where T : struct
{
private bool hasValue;
internal T value;
[System.Runtime.Versioning.NonVersionable]
public Nullable(T value) {
this.value = value;
this.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>(T value) {
return new Nullable<T>(value);
}
[System.Runtime.Versioning.NonVersionable]
public static explicit operator T(Nullable<T> value) {
return value.Value;
}
// The following already obsoleted methods were removed:
// public int CompareTo(object other)
// public int CompareTo(Nullable<T> other)
// public bool Equals(Nullable<T> other)
// public static Nullable<T> 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<Nullable<T>>.CompareTo(Nullable<T> other)
// bool IEquatable<Nullable<T>>.Equals(Nullable<T> other)
}
[System.Runtime.InteropServices.ComVisible(true)]
public static class Nullable
{
[System.Runtime.InteropServices.ComVisible(true)]
public static int Compare<T>(Nullable<T> n1, Nullable<T> n2) where T : struct
{
if (n1.HasValue) {
if (n2.HasValue) return Comparer<T>.Default.Compare(n1.value, n2.value);
return 1;
}
if (n2.HasValue) return -1;
return 0;
}
[System.Runtime.InteropServices.ComVisible(true)]
public static bool Equals<T>(Nullable<T> n1, Nullable<T> n2) where T : struct
{
if (n1.HasValue) {
if (n2.HasValue) return EqualityComparer<T>.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("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<T>(Nullable<T> value)
// public static T GetValueOrDefault<T>(Nullable<T> value)
// public static T GetValueOrDefault<T>(Nullable<T> value, T valueWhenNull)
// The following newly obsoleted methods were removed:
// public static Nullable<T> FromObject<T>(object value)
// public static object ToObject<T>(Nullable<T> value)
// public static object Wrap(object value, Type type)
// public static object Unwrap(object value)
}
}
|