summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Object.cs
blob: 8df1caa9e5212c89789ce389a9f57afafd4b2449 (plain)
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
// 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.

/*============================================================
**
**
**
** Object is the root class for all CLR objects.  This class
** defines only the basics.
**
** 
===========================================================*/

namespace System
{
    using System;
    using System.Runtime;
    using System.Runtime.InteropServices;
    using System.Runtime.CompilerServices;
    using System.Runtime.ConstrainedExecution;
    using System.Runtime.Versioning;
    using System.Diagnostics.Contracts;
    using CultureInfo = System.Globalization.CultureInfo;
    using FieldInfo = System.Reflection.FieldInfo;
    using BindingFlags = System.Reflection.BindingFlags;

    // The Object is the root class for all object in the CLR System. Object 
    // is the super class for all other CLR objects and provide a set of methods and low level
    // services to subclasses.  These services include object synchronization and support for clone
    // operations.
    // 
    //This class contains no data and does not need to be serializable 
    [Serializable]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [System.Runtime.InteropServices.ComVisible(true)]
    [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
    public class Object
    {
        // Creates a new instance of an Object.
        [System.Runtime.Versioning.NonVersionable]
        public Object()
        {
        }

        // Returns a String which represents the object instance.  The default
        // for an object is to return the fully qualified name of the class.
        // 
        public virtual String ToString()
        {
            return GetType().ToString();
        }

        // Returns a boolean indicating if the passed in object obj is 
        // Equal to this.  Equality is defined as object equality for reference
        // types and bitwise equality for value types using a loader trick to
        // replace Equals with EqualsValue for value types).
        // 

        public virtual bool Equals(Object obj)
        {
            return RuntimeHelpers.Equals(this, obj);
        }

        public static bool Equals(Object objA, Object objB)
        {
            if (objA == objB)
            {
                return true;
            }
            if (objA == null || objB == null)
            {
                return false;
            }
            return objA.Equals(objB);
        }

        [System.Runtime.Versioning.NonVersionable]
        public static bool ReferenceEquals(Object objA, Object objB)
        {
            return objA == objB;
        }

        // GetHashCode is intended to serve as a hash function for this object.
        // Based on the contents of the object, the hash function will return a suitable
        // value with a relatively random distribution over the various inputs.
        //
        // The default implementation returns the sync block index for this instance.
        // Calling it on the same object multiple times will return the same value, so
        // it will technically meet the needs of a hash function, but it's less than ideal.
        // Objects (& especially value classes) should override this method.
        // 
        public virtual int GetHashCode()
        {
            return RuntimeHelpers.GetHashCode(this);
        }

        // Returns a Type object which represent this object instance.
        // 
        [Pure]
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        public extern Type GetType();

        // Allow an object to free resources before the object is reclaimed by the GC.
        // 
        [System.Runtime.Versioning.NonVersionable]
        ~Object()
        {
        }

        // Returns a new object instance that is a memberwise copy of this 
        // object.  This is always a shallow copy of the instance. The method is protected
        // so that other object may only call this method on themselves.  It is entended to
        // support the ICloneable interface.
        // 
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        protected extern Object MemberwiseClone();


        // Sets the value specified in the variant on the field
        // 
        private void FieldSetter(String typeName, String fieldName, Object val)
        {
            Contract.Requires(typeName != null);
            Contract.Requires(fieldName != null);

            // Extract the field info object
            FieldInfo fldInfo = GetFieldInfo(typeName, fieldName);

            if (fldInfo.IsInitOnly)
                throw new FieldAccessException(SR.FieldAccess_InitOnly);

            // Make sure that the value is compatible with the type
            // of field
            Type pt = fldInfo.FieldType;
            if (pt.IsByRef)
            {
                pt = pt.GetElementType();
            }

            if (!pt.IsInstanceOfType(val))
            {
                val = Convert.ChangeType(val, pt, CultureInfo.InvariantCulture);
            }

            // Set the value
            fldInfo.SetValue(this, val);
        }

        // Gets the value specified in the variant on the field
        // 
        private void FieldGetter(String typeName, String fieldName, ref Object val)
        {
            Contract.Requires(typeName != null);
            Contract.Requires(fieldName != null);

            // Extract the field info object
            FieldInfo fldInfo = GetFieldInfo(typeName, fieldName);

            // Get the value
            val = fldInfo.GetValue(this);
        }

        // Gets the field info object given the type name and field name.
        // 
        private FieldInfo GetFieldInfo(String typeName, String fieldName)
        {
            Contract.Requires(typeName != null);
            Contract.Requires(fieldName != null);
            Contract.Ensures(Contract.Result<FieldInfo>() != null);

            Type t = GetType();
            while (null != t)
            {
                if (t.FullName.Equals(typeName))
                {
                    break;
                }

                t = t.BaseType;
            }

            if (null == t)
            {
                throw new ArgumentException();
            }

            FieldInfo fldInfo = t.GetField(fieldName, BindingFlags.Public |
                                                      BindingFlags.Instance |
                                                      BindingFlags.IgnoreCase);
            if (null == fldInfo)
            {
                throw new ArgumentException();
            }

            return fldInfo;
        }
    }


    // Internal methodtable used to instantiate the "canonical" methodtable for generic instantiations.
    // The name "__Canon" will never been seen by users but it will appear a lot in debugger stack traces
    // involving generics so it is kept deliberately short as to avoid being a nuisance.

    [ClassInterface(ClassInterfaceType.AutoDual)]
    [System.Runtime.InteropServices.ComVisible(true)]
    internal class __Canon
    {
    }

    // This class is used to define the name of the base class library
    internal class CoreLib
    {
        public const string Name = "System.Private.CoreLib";

        public static string FixupCoreLibName(string strToFixup)
        {
            if (!String.IsNullOrEmpty(strToFixup))
            {
                strToFixup = strToFixup.Replace("mscorlib", System.CoreLib.Name);
            }

            return strToFixup;
        }
    }
}