[Serializable] |
Because all classes in the .NET Framework are derived from Object, every method defined in the Object class is available in all objects in the system. Derived classes can and do override some of these methods, including:
ctor #1 | Default constructor. This constructor is called by derived class constructors to initialize state in this type. Initializes a new instance of the Object class. |
Equals | Overloaded:Equals(object obj) Determines whether the specified Object is equal to the current Object. |
Equals | Overloaded:Equals(object objA, object objB) Determines whether the specified Object instances are considered equal. |
GetHashCode | Serves as a hash function for a particular type, suitable for use in hashing algorithms and data structures like a hash table. |
GetType | Gets the Type of the current instance. |
ReferenceEquals | Determines whether the specified Object instances are the same instance. |
ToString | Returns a String that represents the current Object. |
Finalize | Overridden: Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. |
MemberwiseClone | Creates a shallow copy of the current Object. |
public Object(); |
obj
For reference types, equality is defined as object equality; that is, whether the references refer to the same object. For value types, equality is defined as bitwise equality. The ValueType class supports value types.
This method can be overridden by a derived class. For example, many of the base data types return true if both objects represent the same value; otherwise, false.
This method only compares primitives and objects. It must be overridden to compare more complex structures, such as arrays of objects.
The following statements must be true for all implementations of the Object.Equals method. In the list, x, y, and z represent object references that are not null.
See Object.GetHashCode for additional required behaviors pertaining to the Object.Equals method.
Implementations of Object.Equals must not throw exceptions.
For some kinds of objects, it is desirable to have Object.Equals test for value equality instead of referential equality. Such implementations of Object.Equals return true if the two objects have the same "value", even if they are not the same instance. The type's implementer decides what constitutes an object's "value", but it is typically some or all the data stored in the instance variables of the object. For example, the value of a String is based on the characters of the string; the Object.Equals method of the String class returns true for any two string instances that contain exactly the same characters in the same order.
Types that implement IComparable must override Object.Equals.
Types that override Object.Equals must also override Object.GetHashCode; otherwise, Hashtable might not work correctly.
If your programming language supports operator overloading and if you choose to overload the equality operator for a given type, that type should override the Object.Equals method. Such implementations of the Object.Equals method should return the same results as the equality operator. Following this guideline will help ensure that class library code using Object.Equals (such as ArrayList and Hashtable) behaves in a manner that is consistent with the way the equality operator is used by application code.
The following guidelines are for implementing a value type:
The following guidelines are for implementing a reference type:
using System; public class Sample { void Method() { Object Obj1 = new Object(); Object Obj2 = new Object(); Console.WriteLine(Obj1.Equals(Obj2)); //===> false Obj2 = Obj1; Console.WriteLine(Obj1.Equals(Obj2)); //===> true } }
The following example shows a Point class that overrides the Object.Equals method to provide value equality and a class Point3D, which is derived from Point. Because Point 's override of Object.Equals is the first in the inheritance chain to introduce value equality, the Object.Equals method of the base class (which is inherited from Object and checks for referential equality) is not invoked. However, Point3D.Equals invokes Point.Equals because Point implements Object.Equals in a manner that provides value equality.
using System; class Point: Object { protected int x, y; public Point() { this.x = 0; this.y = 0; } public Point(int X, int Y) { this.x = X; this.y = Y; } public override bool Equals(Object obj) { //Check for null and compare run-time types. if (obj == null || GetType() != obj.GetType()) return false; Point p = (Point)obj; return (x == p.x) && (y == p.y); } public override int GetHashCode() { return x ^ y; } } class Point3D: Point { int z; public Point3D(int X, int Y, int Z) { this.x = X; this.y = Y; this.z = Z; } public override bool Equals(Object obj) { return base.Equals(obj) && z == ((Point3D)obj).z; } public override int GetHashCode() { return base.GetHashCode() ^ z; } }
The Point.Equals method checks that the obj argument is not null and that it references an instance of the same type as this object. If either of those checks fail, the method returns false.
The Object.Equals method uses Object.GetType to determine whether the run-time types of the two objects are identical. (Note that typeof is not used here because it returns the static type.) If the method used a check of the form
obj is Point
, the check would return true in cases where obj is an instance of a derived class of Point, even though obj and the current instance are not of the same runtime type. Having verified that both objects are of the same type, the method casts obj to type Point and returns the result of comparing the instance variables of the two objects.
In Point3D.Equals, the inherited Object.Equals method is invoked before anything else is done; the inherited Object.Equals method checks to see that obj is not null, that obj is an instance of the same class as this object and that the inherited instance variables match. Only when the inherited Object.Equals returns true does the method compare the instance variables introduced in the derived class. Specifically, the cast to Point3D is not executed unless obj has been determined to be of type Point3D or a derived class of Point3D.
In the previous example, operator == (the equality operator) is used to compare the individual instance variables. In some cases, it is appropriate to use the Object.Equals method to compare instance variables in an Object.Equals implementation, as shown in the following code example.
using System; class Rectangle { Point a, b; public Rectangle(int upLeftX, int upLeftY, int downRightX, int downRightY) { this.a = new Point(upLeftX, upLeftY); this.b = new Point(downRightX, downRightY); } public override bool Equals(Object obj) { // Performs an equality check on two rectangles (Point object pairs). if (obj == null || GetType() != obj.GetType()) return false; Rectangle r = (Rectangle)obj; //Uses Equals to compare variables. return a.Equals(r.a) && b.Equals(r.b); } public override int GetHashCode() { return a.GetHashCode() ^ b.GetHashCode(); } }
In some languages, such as C#, operator overloading is supported. When a type overloads operator ==, it should also override the Object.Equals method to provide the same functionality. This is typically accomplished by writing the Object.Equals method in terms of the overloaded operator ==, as in the following code example.
using System; public struct Complex { public double re, im; public override bool Equals(Object obj) { return obj is Complex && this == (Complex)obj; } public override int GetHashCode() { return re.GetHashCode() ^ im.GetHashCode(); } public static bool operator ==(Complex x, Complex y) { return x.re == y.re && x.im == y.im; } public static bool operator !=(Complex x, Complex y) { return !(x == y); } }
Because Complex is a C# struct (a value type), it cannot be derived from; therefore, the Object.Equals method need not compare the Object.GetType results for each object, but can instead use the is operator to check the type of the obj parameter.
objA
objB
objA.Equals(objB)
returns true; otherwise, false.For reference types, equality is defined as object equality; that is, whether the references refer to the same object. For value types, equality is defined as bitwise equality. The ValueType class supports value types.
This method first determines whether both parameters are null references before calling
objA.Equals(objB)
.
using System; public class MyClass { public static void Main() { string s1 = "Tom"; string s2 = "Carol"; Console.WriteLine("Object.Equals(\"{0}\", \"{1}\") => {2}", s1, s2, Object.Equals(s1, s2)); s1 = "Tom"; s2 = "Tom"; Console.WriteLine("Object.Equals(\"{0}\", \"{1}\") => {2}", s1, s2, Object.Equals(s1, s2)); s1 = null; s2 = "Tom"; Console.WriteLine("Object.Equals(null, \"{1}\") => {2}", s1, s2, Object.Equals(s1, s2)); s1 = "Carol"; s2 = null; Console.WriteLine("Object.Equals(\"{0}\", null) => {2}", s1, s2, Object.Equals(s1, s2)); s1 = null; s2 = null; Console.WriteLine("Object.Equals(null, null) => {2}", s1, s2, Object.Equals(s1, s2)); } } /* This code produces the following output. Object.Equals("Tom", "Carol") => False Object.Equals("Tom", "Tom") => True Object.Equals(null, "Tom") => False Object.Equals("Carol", null) => False Object.Equals(null, null) => True */
~Object(); |
This method is automatically called after an object becomes inaccessible, unless the object has been exempted from finalization by a call to GC.SuppressFinalize. During shutdown of an application domain, Finalize is automatically called on objects that are not exempt from finalization, even those that are still accessible.Finalize is automatically called only once on a given instance, unless the object is re-registered using a mechanism such as GC.ReRegisterForFinalize and GC.SuppressFinalize has not been subsequently called.
Every implementation of Object.Finalize in a derived type must call its base type's implementation of Object.Finalize. This is the only case in which application code is allowed to call Object.Finalize.
Object.Finalize operations have the following limitations:
The Object.Finalize method might not run to completion or might not run at all in the following exceptional circumstances:
The runtime continues to Finalize objects during shutdown only while the number of finalizable objects continues to decrease.
If Object.Finalize or an override of Object.Finalize throws an exception, the runtime ignores the exception, terminates that Object.Finalize method, and continues the finalization process.
Object.Finalize does nothing by default. It must be overridden by a derived class only if necessary, because reclamation during garbage collection tends to take much longer if a Object.Finalize operation must be run.
If an Object holds references to any resources, Object.Finalize must be overridden by a derived class in order to free these resources before the Object is discarded during garbage collection.
A type should implement Object.Finalize when it uses unmanaged resources such as file handles or database connections that must be released when the managed object that uses them is reclaimed. See the IDisposable interface for a complementary and more controllable means of disposing resources.
Object.Finalize can take any action, including resurrecting an object (that is, making the object accessible again) after it has been cleaned up during garbage collection. However, the object can only be resurrected once; Object.Finalize cannot be called on resurrected objects during garbage collection.
Destructors are the C# mechanism for performing cleanup operations. Destructors provide appropriate safeguards, such as automatically calling the base type's destructor. In C# code, Object.Finalize cannot be called or overridden.
public virtual int GetHashCode(); |
This implementation of Object.GetHashCode can only guarantee that the same hash code will be returned for the same instance; it cannot guarantee that different instances will have different hash codes or that two objects referring to the same value will have the same hash codes. Different versions of the .NET Framework might also generate different hash codes for the same instance. Therefore, do not persist hash codes to files or send them over the network. To guarantee the same hash code for the same object, you must define your own immutable hash function using the IHashCodeProvider interface and use it consistently.
The default implementation returns an index for the object determined by the common language runtime. The index is unique to an instance of an object within an AppDomain for an instance of the executing engine. However, because this index can be reused after the object is reclaimed during garbage collection, it is possible to obtain the same hash code for two different objects. Also, two objects that represent the same value have the same hash code only if they are the exact same object. This implementation is not particularly useful for hashing; therefore, derived classes should override Object.GetHashCode.
A hash function is used to quickly generate a number (hash code) that corresponds to the value of an object. Hash functions are usually specific to each Type and should use at least one of the instance fields as input.
A hash function must have the following properties:
For example, the implementation of String.GetHashCode provided by the String class returns unique hash codes for unique string values. Therefore, two String objects return the same hash code if they represent the same string value. Also, the method uses all the characters in the string to generate reasonably randomly distributed output, even when the input is clustered in certain ranges (for example, many users might have strings that contain only the lower 128 ASCII characters, even though a string can contain any of the 65,535 Unicode characters).
Object.GetHashCode must always return the same value for a given instance of the object. One way to ensure this is by basing the hash code on an immutable data member. For derived classes of Object, Object.GetHashCode can delegate to the Object.GetHashCode implementation, if and only if that derived class defines value equality to be reference equality and the type is not a value type.
Providing a good hash function on a class can significantly affect the performance of adding those objects to a hash table. In a hash table with a good implementation of a hash function, searching for an element takes constant time (for example, an O(1) operation). In a hash table with a poor implementation of a hash function, the performance of a search depends on the number of items in the hash table (for example, an O(n) operation, where n is the number of items in the hash table). Hash functions should also be inexpensive to compute.
Implementations of Object.GetHashCode must not result in circular references. For example, if ClassA.GetHashCode calls ClassB.GetHashCode, ClassB.GetHashCode must not call ClassA.GetHashCode either directly or indirectly.
Implementations of GetHashCode must not throw exceptions.
Derived classes that override Object.GetHashCode must also override Object.Equals to guarantee that two objects considered equal have the same hash code; otherwise, Hashtable might not work correctly.
using System; public struct Int32 { public int value; //other methods... public override int GetHashCode() { return value; } }
Frequently, a type has multiple data fields that can participate in generating the hash code. One way to generate a hash code is to combine these fields using an XOR (eXclusive OR) operation, as shown in the following code example.
using System; public struct Point { public int x; public int y; //other methods public override int GetHashCode() { return x ^ y; } }
The following code example illustrates another case where the type's fields are combined using XOR (eXclusive OR) to generate the hash code. Notice that in this code example, the fields represent user-defined types, each of which implements Object.GetHashCode and Object.Equals.
using System; public class SomeType { public override int GetHashCode() { return 0; } } public class AnotherType { public override int GetHashCode() { return 1; } } public class LastType { public override int GetHashCode() { return 2; } } public class MyClass { SomeType a = new SomeType(); AnotherType b = new AnotherType(); LastType c = new LastType(); public override int GetHashCode () { return a.GetHashCode() ^ b.GetHashCode() ^ c.GetHashCode(); } }
If the data member of the derived class is bigger than an Int32, you can combine the high order bits of the value with the low order bits using an XOR (eXclusive OR) operation, as shown in the following code example.
using System; public struct Int64 { public long value; //other methods... public override int GetHashCode() { return ((int)value ^ (int)(value >> 32)); } }
public Type GetType(); |
Object.ReferenceEquals(x.GetType(),y.GetType())
returns true.The Type object exposes the metadata associated with the class of the current Object.
using System; public class MyBaseClass: Object { } public class MyDerivedClass: MyBaseClass { } public class Test { public static void Main() { MyBaseClass myBase = new MyBaseClass(); MyDerivedClass myDerived = new MyDerivedClass(); object o = myDerived; MyBaseClass b = myDerived; Console.WriteLine("mybase: Type is {0}", myBase.GetType()); Console.WriteLine("myDerived: Type is {0}", myDerived.GetType()); Console.WriteLine("object o = myDerived: Type is {0}", o.GetType()); Console.WriteLine("MyBaseClass b = myDerived: Type is {0}", b.GetType()); } } /* This code produces the following output. mybase: Type is MyBaseClass myDerived: Type is MyDerivedClass object o = myDerived: Type is MyDerivedClass MyBaseClass b = myDerived: Type is MyDerivedClass */
protected object MemberwiseClone(); |
A shallow copy creates a new instance of the same type as the original object, and then copies the non-static fields of the original object. If the field is a value type, a bit-by-bit copy of the field is performed. If the field is a reference type, the reference is copied but the referred object is not; therefore, the reference in the original object and the reference in the clone point to the same object. In contrast, a deep copy of an object duplicates everything directly or indirectly referenced by the fields in the object.
For example, if X is an Object with references to the objects A and B, and the object A also has a reference to an object M, a shallow copy of X is an object Y, which also has references to objects A and B. In contrast, a deep copy of X is an object Y with direct references to objects C and D, and an indirect reference to object N, where C is a copy of A, D is a copy of B, and N is a copy of M.
The Type of the clone is the same as the type of the original Object.
using System; class MyBaseClass { public static string CompanyName = "My Company"; public int age; public string name; } class MyDerivedClass: MyBaseClass { static void Main() { // Creates an instance of MyDerivedClass and assign values to its fields. MyDerivedClass m1 = new MyDerivedClass(); m1.age = 42; m1.name = "Sam"; // Performs a shallow copy of m1 and assign it to m2. MyDerivedClass m2 = (MyDerivedClass) m1.MemberwiseClone(); } }
objA
objB
using System; class MyClass { static void Main() { object o = null; object p = null; object q = new Object(); Console.WriteLine(Object.ReferenceEquals(o, p)); p = q; Console.WriteLine(Object.ReferenceEquals(p, q)); Console.WriteLine(Object.ReferenceEquals(o, p)); } } /* This code produces the following output. True True False */
public virtual string ToString(); |
The default implementation returns the fully qualified name of the type of the Object.
using System; public class Sample { void Method() { // Prints out: "System.Object" Object o = new Object(); Console.WriteLine (o.ToString()); } }