4 // Martin Baulig (martin@ximian.com)
6 // (C) 2004 Novell, Inc.
10 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Reflection;
34 using System.Collections.Generic;
36 using System.Runtime.CompilerServices;
40 public static class Nullable {
41 public static int Compare<T> (Nullable<T> left, Nullable<T> right) where T: struct
43 IComparable icomparable = left.value as IComparable;
44 if (icomparable == null)
45 throw new ArgumentException ("At least one object must implement IComparable.");
46 if (left.has_value == false && right.has_value == false)
53 return icomparable.CompareTo (right.value);
56 public static bool Equals<T> (Nullable <T> value1, Nullable<T> value2) where T: struct
58 return value1.Equals (value2);
61 public static Type GetUnderlyingType (Type nullableType)
63 if (nullableType == null)
64 throw new ArgumentNullException ("nullableType");
65 if (nullableType.IsGenericType && nullableType.GetGenericTypeDefinition () == typeof (Nullable<>))
66 return nullableType.GetGenericArguments ()[0];
73 public struct Nullable<T> where T: struct
75 #region Sync with runtime code
77 internal bool has_value;
80 public Nullable (T value)
82 this.has_value = true;
86 public bool HasValue {
87 get { return has_value; }
93 throw new InvalidOperationException ("Nullable object must have a value.");
99 public override bool Equals (object other)
102 return has_value == false;
103 if (!(other is Nullable<T>))
106 return Equals ((Nullable <T>) other);
109 bool Equals (Nullable<T> other)
111 Nullable<T> no = (Nullable<T>) other;
112 if (no.has_value != has_value)
115 if (has_value == false)
118 return no.value.Equals (value);
121 public override int GetHashCode ()
126 return value.GetHashCode ();
129 public T GetValueOrDefault ()
131 return GetValueOrDefault (default (T));
134 public T GetValueOrDefault (T def_value)
142 public override string ToString ()
145 return value.ToString ();
150 public static implicit operator Nullable<T> (T value)
152 return new Nullable<T> (value);
155 public static explicit operator T (Nullable<T> value)
160 // These are called by the JIT
161 // Ironicly, the C# code is the same for these two,
162 // however, on the inside they do somewhat different things
163 static object Box (T? o)
170 static T? Unbox (object o)