using System.Collections.Generic;
#endif
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
#if NET_2_0
namespace System {
+#if NET_2_0
+ [ComVisible (true)]
+#endif
public static class Nullable {
- public static int Compare<T> (Nullable<T> left, Nullable<T> right)
+ public static int Compare<T> (Nullable<T> left, Nullable<T> right) where T: struct
{
IComparable icomparable = left.value as IComparable;
if (icomparable == null)
return icomparable.CompareTo (right.value);
}
- public static bool Equals<T> (Nullable <T> value1, Nullable<T> value2)
+ public static bool Equals<T> (Nullable <T> value1, Nullable<T> value2) where T: struct
{
return value1.Equals (value2);
}
- public static Nullable<T> FromObject<T> (object value)
- {
- if (!(value is T))
- throw new ArgumentException ("Object type can not be converted to target type.");
-
- return new Nullable<T> ((T) value);
- }
-
- public static T GetValueOrDefault<T>(Nullable<T> value)
- {
- return GetValueOrDefault<T> (value, default (T));
- }
-
- public static T GetValueOrDefault<T> (Nullable<T> value, T defaultValue)
- {
- if (!value.has_value)
- return defaultValue;
-
- return value.value;
- }
-
- public static bool HasValue<T> (Nullable <T> value)
- {
- return value.has_value;
- }
-
- public static object ToObject<T> (Nullable<T> value)
+ public static Type GetUnderlyingType (Type nullableType)
{
- if (!value.has_value)
+ if (nullableType == null)
+ throw new ArgumentNullException ("nullableType");
+ if (nullableType.IsGenericType && nullableType.GetGenericTypeDefinition () == typeof (Nullable<>))
+ return nullableType.GetGenericArguments ()[0];
+ else
return null;
-
- return (object)value.value;
}
}
-
- public struct Nullable<T> : IComparable, INullableValue
+
+ [Serializable]
+ public struct Nullable<T> where T: struct
{
+ #region Sync with runtime code
internal T value;
internal bool has_value;
+ #endregion
public Nullable (T value)
{
- if (value == null)
- this.has_value = false;
- else
- this.has_value = true;
-
+ this.has_value = true;
this.value = value;
}
}
}
- object INullableValue.Value {
- get {
- return (object)Value;
- }
- }
-
- [Obsolete]
- public int CompareTo (Nullable<T> other)
- {
- return Nullable.Compare<T> (this, other);
- }
-
- [Obsolete]
- public int CompareTo (object other)
- {
- if (!(other is Nullable<T>))
- throw new ArgumentException ("Object type can not be converted to target type.");
-
- return Nullable.Compare<T> (this, (Nullable<T>) other);
- }
-
public override bool Equals (object other)
{
+ if (other == null)
+ return has_value == false;
if (!(other is Nullable<T>))
return false;
return Equals ((Nullable <T>) other);
}
- public bool Equals (Nullable<T> other)
+ bool Equals (Nullable<T> other)
{
- if (other.has_value != has_value)
+ Nullable<T> no = (Nullable<T>) other;
+ if (no.has_value != has_value)
return false;
if (has_value == false)
return true;
- return other.value.Equals (value);
- }
-
- [Obsolete]
- public static Nullable<T> FromObject (object value)
- {
- return Nullable.FromObject<T> (value);
+ return no.value.Equals (value);
}
public override int GetHashCode ()
return value.GetHashCode ();
}
- [Obsolete]
public T GetValueOrDefault ()
{
- return Nullable.GetValueOrDefault<T> (this, default (T));
+ return GetValueOrDefault (default (T));
}
- [Obsolete]
public T GetValueOrDefault (T def_value)
- {
- return Nullable.GetValueOrDefault<T> (this, def_value);
- }
-
- public object ToObject ()
{
if (!has_value)
- return null;
-
- return (object)value;
+ return def_value;
+ else
+ return value;
}
public override string ToString ()
if (has_value)
return value.ToString ();
else
- return "";
+ return String.Empty;
}
public static implicit operator Nullable<T> (T value)
return value.Value;
}
- public static bool operator == (Nullable<T> left, Nullable<T> right)
- {
- return left.Equals (right);
- }
-
- public static bool operator != (Nullable<T> left, Nullable<T> right)
- {
- return !left.Equals (right);
- }
-
-
// These are called by the JIT
// Ironicly, the C# code is the same for these two,
// however, on the inside they do somewhat different things