Bump corefx
[mono.git] / mcs / class / referencesource / mscorlib / system / object.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 /*============================================================
7 **
8 ** Class:  Object
9 **
10 **
11 ** Object is the root class for all CLR objects.  This class
12 ** defines only the basics.
13 **
14 ** 
15 ===========================================================*/
16
17 namespace System {
18     using System;
19     using System.Runtime;
20     using System.Runtime.InteropServices;
21     using System.Runtime.CompilerServices;
22     using System.Runtime.ConstrainedExecution;
23     using System.Runtime.Versioning;
24     using System.Diagnostics.Contracts;
25     using CultureInfo = System.Globalization.CultureInfo;
26     using FieldInfo = System.Reflection.FieldInfo;
27     using BindingFlags = System.Reflection.BindingFlags;
28 #if FEATURE_REMOTING        
29     using RemotingException = System.Runtime.Remoting.RemotingException;    
30 #endif
31 // The Object is the root class for all object in the CLR System. Object 
32 // is the super class for all other CLR objects and provide a set of methods and low level
33 // services to subclasses.  These services include object synchronization and support for clone
34 // operations.
35 // 
36  //This class contains no data and does not need to be serializable 
37 [Serializable]
38 [ClassInterface(ClassInterfaceType.AutoDual)]
39 [System.Runtime.InteropServices.ComVisible(true)]
40 public class Object
41 {
42     // Creates a new instance of an Object.
43     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
44     [System.Runtime.Versioning.NonVersionable]
45     public Object()
46     {            
47     }
48             
49     // Returns a String which represents the object instance.  The default
50     // for an object is to return the fully qualified name of the class.
51     // 
52     public virtual String ToString()
53     {
54         return GetType().ToString();
55     }
56     
57     // Returns a boolean indicating if the passed in object obj is 
58     // Equal to this.  Equality is defined as object equality for reference
59     // types and bitwise equality for value types using a loader trick to
60     // replace Equals with EqualsValue for value types).
61     // 
62     
63     public virtual bool Equals(Object obj)
64     {
65         return RuntimeHelpers.Equals(this, obj);
66     }
67
68     public static bool Equals(Object objA, Object objB) 
69     {
70         if (objA==objB) {
71             return true;
72         }
73         if (objA==null || objB==null) {
74             return false;
75         }
76         return objA.Equals(objB);
77     }
78
79     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
80     [System.Runtime.Versioning.NonVersionable]
81     public static bool ReferenceEquals (Object objA, Object objB) {
82         return objA == objB;
83     }
84     
85     // GetHashCode is intended to serve as a hash function for this object.
86     // Based on the contents of the object, the hash function will return a suitable
87     // value with a relatively random distribution over the various inputs.
88     //
89     // The default implementation returns the sync block index for this instance.
90     // Calling it on the same object multiple times will return the same value, so
91     // it will technically meet the needs of a hash function, but it's less than ideal.
92     // Objects (& especially value classes) should override this method.
93     // 
94     public virtual int GetHashCode()
95     {
96         return RuntimeHelpers.GetHashCode(this);
97     }
98     
99     // Returns a Type object which represent this object instance.
100     // 
101     [System.Security.SecuritySafeCritical]  // auto-generated
102     [Pure]
103     [ResourceExposure(ResourceScope.None)]
104     [MethodImplAttribute(MethodImplOptions.InternalCall)]
105     public extern Type GetType();
106
107     // Allow an object to free resources before the object is reclaimed by the GC.
108     // 
109     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
110     [System.Runtime.Versioning.NonVersionable]
111     ~Object()
112     {
113     }
114     
115     // Returns a new object instance that is a memberwise copy of this 
116     // object.  This is always a shallow copy of the instance. The method is protected
117     // so that other object may only call this method on themselves.  It is entended to
118     // support the ICloneable interface.
119     // 
120     [System.Security.SecuritySafeCritical]  // auto-generated
121     [ResourceExposure(ResourceScope.None)]
122     [MethodImplAttribute(MethodImplOptions.InternalCall)]
123     protected extern Object MemberwiseClone();
124     
125    
126     // Sets the value specified in the variant on the field
127     // 
128     [System.Security.SecurityCritical]  // auto-generated
129     private void FieldSetter(String typeName, String fieldName, Object val)
130     {
131         Contract.Requires(typeName != null);
132         Contract.Requires(fieldName != null);
133
134         // Extract the field info object
135         FieldInfo fldInfo = GetFieldInfo(typeName, fieldName);
136
137         if (fldInfo.IsInitOnly)
138             throw new FieldAccessException(Environment.GetResourceString("FieldAccess_InitOnly"));
139
140         // Make sure that the value is compatible with the type
141         // of field
142 #if FEATURE_REMOTING        
143         System.Runtime.Remoting.Messaging.Message.CoerceArg(val, fldInfo.FieldType);    
144 #else
145         Type pt=fldInfo.FieldType;
146         if (pt.IsByRef) 
147         {
148             pt = pt.GetElementType();
149         }
150     
151         if (!pt.IsInstanceOfType(val))
152         {
153             val = Convert.ChangeType(val, pt, CultureInfo.InvariantCulture);
154         }
155
156 #endif
157
158         // Set the value            
159         fldInfo.SetValue(this, val);
160     }
161     
162     // Gets the value specified in the variant on the field
163     // 
164     private void FieldGetter(String typeName, String fieldName, ref Object val)
165     {
166         Contract.Requires(typeName != null);
167         Contract.Requires(fieldName != null);
168
169         // Extract the field info object
170         FieldInfo fldInfo = GetFieldInfo(typeName, fieldName);
171
172         // Get the value
173         val = fldInfo.GetValue(this);            
174     }
175
176     // Gets the field info object given the type name and field name.
177     // 
178     private FieldInfo GetFieldInfo(String typeName, String fieldName)
179     {
180         Contract.Requires(typeName != null);
181         Contract.Requires(fieldName != null);
182         Contract.Ensures(Contract.Result<FieldInfo>() != null);
183
184         Type t = GetType();
185         while(null != t)
186         {
187             if(t.FullName.Equals(typeName))
188             {
189                 break;
190             }
191
192             t = t.BaseType;
193         }
194         
195         if (null == t)
196         {
197 #if FEATURE_REMOTING         
198             throw new RemotingException(String.Format(
199                 CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_BadType"),
200                                               typeName));
201 #else
202             throw new ArgumentException();
203 #endif
204         }
205
206         FieldInfo fldInfo = t.GetField(fieldName, BindingFlags.Public | 
207                                                   BindingFlags.Instance | 
208                                                   BindingFlags.IgnoreCase);
209         if(null == fldInfo)
210         {
211 #if FEATURE_REMOTING 
212             throw new RemotingException(String.Format(
213                 CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_BadField"),
214                                               fieldName, typeName));            
215 #else
216             throw new ArgumentException();
217 #endif
218
219         }
220         
221         return fldInfo;
222     }
223 }
224
225
226 // Internal methodtable used to instantiate the "canonical" methodtable for generic instantiations.
227 // The name "__Canon" will never been seen by users but it will appear a lot in debugger stack traces
228 // involving generics so it is kept deliberately short as to avoid being a nuisance.
229
230 [Serializable]
231 [ClassInterface(ClassInterfaceType.AutoDual)]
232 [System.Runtime.InteropServices.ComVisible(true)]
233 internal class __Canon
234 {
235 }
236
237 }