Learning your language for .NET programming is a challenge in its own right, learning to use and exploit the .NET framework to its fullest is even harder due the mere fact of the size of the framework. However, there is one class in the framework you should master and that is the System.Object class.
System.Object defines the basic behaviour of all managed data types and thus all managed data types within the framework, be it a value or reference types. Every managed type inherits from System.Object, either directly or indirectly. A reference type (class) may inherit from another explicit class, however ultimately they all will inherit from System.Object.
Reference Types and System.Object
Take the following set of classes:
class Animal
{ }
class Mammal : Animal
{ }
class Dog : Mammal
{ }
Dog inherits from Mammal, thus dog gains all characteristics of a Mammal and its own members. Mammal however inherits from animal, thus both Dog and Mammal get all the characteristics of the Animal. In this example, Animal does not inherit from anything explicitly. Don't be fooled by this as in reality Animal does inherit from system object. You may have written the class
class Animal: System.Object
{ }
In C#, the keyword object is an alias for System.Object, thus the code below is the same as above.
class Animal : object
{ }
Value Types and System.Object
Value types (struct) on the other hand do not support inheritance directly, let us take the following value type as an example:
struct Point
{ }
This struct automatically inherits from System.ValueType (a class) which in turn inherits from System.Object. Thus one could theoretically say that a structure is a class, however it has a different memory model to a class.
System.Object Members
Now we all know the rules, and it is not necessary for you to explicitly inherit from object. It is automatically implied and all .NET programmers should know this. This section now describes the member methods of the System.Object class and answers the begging question of what you can do with it.
Constructor
public Object();
The default constructor of System.Object is called every time an instance of an object is created. The System.Object only has a default constructor (no parameters).
Equals
public virtual bool Equals(object obj)
public static bool Equals(object objA, object objB)
The Equals method is used to compare whether two objects are in fact the identical. However, there is a twist to their tail. For reference type objects, the objects identity is actually checked, i.e. Are they the same physical object in memory?. Value Types are different as a compare will check the state, i.e. The actual values are compared. It is common practice to override the Equals method to perform proper equality checking.
Finalize
public override void Finalize()
This method is called on every instance of objects in memory when the garbage collector is in the process of freeing the memory. This method will then be used to free up unmanaged resources used by the object. In C#, you will not be able to override this directly as other methods as Finalize is implemented as a destructor ~Class(). When you compile your project and view the MSIL you will notice that ~Class() will be converted into a Finalize method.
GetHashCode
public virtual int GetHashCode()
A hash code is normally created to uniquely identify the object. A default hash code is automatically generated when an object is created, this has code may have some interesting issues. Firstly hash codes are not evenly distributed, that is they are not sequential and completely random. Secondly the default hash code is not guaranteed to be unique. These has codes are often used in collections to uniquely define a key or whether an object exists. In reality the likelihood of two hash codes being the same is slim, You will be able to override and generate your own hash code that uniquely identifies the object.
GetType
public Type GetType()
This method returns at System.Type reference to the object. This nifty little method allows you to then inspect the data type and programmatically work with the data type. It thus returns the metadata of your object. I.e. You will write code to interrogate the data type and adjust accordingly, welcome to the start of Reflection.
MemberWiseClone
protected object MemberwiseClone()
MemberwiseClone is used to create a new copy of the object. It is a protected method and thus can only be accessed from child classes. It cannot be overridden. MemberwiseClone creates what we call a shallow copy, it will copy the data from the object to the clone. Value type member fields will have their data copied, however, reference type member objects will only have their object references copied. I.e. Should you clone a object that has a member which is a reference type, both the original and the clone will point to the same member of Reference type.
ReferenceEquals
public static bool ReferenceEquals(object objA, object objB)
This method compares whether two object reside at the same memory location, their values or state are not compared.
ToString
public virtual string ToString()
The ToString() method is used to return a string representation of the current instance. The default behaviour of this method is to return the fully qualified name of the Type. Override this method to implement a better representation of data of your method.