Q:

What is the purpose of casting into "object" type?

I have found code on a website which is as follows.
 string a = "xx";
 string b = "xx";
 string c = "x";
 string d = String.Intern(c + c);

 Console.WriteLine((object)a == (object)b); // True
 Console.WriteLine((object)a == (object)d); // True

Here, what is the purpose of casting into object type again since a,b,d are itself the objects of string?

A:

The C# compiler will try to get all constant strings at compile time. This is called string interning. So after the code generated a and b are references to the same string which contains "xx".
You can check this by comparing their references (casting them to object and do the equality check or use object.ReferenceEquals). Keep in mind that == operator for strings compare their values not their references. 
Another thing to mention is that strings are immutable in .NET.
string a = "xx";
string b = "x" + "x"; // String interning here
string c = string.Join("", new[] { "x", "x" }); // No interning here because it is evaluated at runtime

Console.WriteLine((object)a == (object)b); // True. Reference check
Console.WriteLine(a == b); // True. Value check

Console.WriteLine((object)a == c); //False. Reference check. Described below
Console.WriteLine(a == c); // True. Value check

So why is Console.WriteLine((object)a == c); doing a reference check?? Because the compiler will choose the == operator on object which checks for reference equality.

So the whole point of casting to object in your question is to check if string interning works or not. Assuming that there is no interning happen at compile time.
 string a = "xx";
 string b = "xx";
 string c = "x";
 string d = String.Intern(c + c);

Then Console.WriteLine((object)a == (object)b); would print "False", because a and b are references for two different string in memory, both of which look like "xx".

A:

An addition to the provided answer:
string (C# Reference)

The System.String class is an immutable reference type provided in
  the .NET framework class library. This class creates a new string
  object internally for any string manipulation action. The contents of
  objects of this type do not change, although the syntax makes it
  appear as if contents can be changed. In addition, string is used as
  hash table key for the computation of hash values to avoid the risk of
  corrupting the hash data structure.

Example:
string a = "hello";
string b = "h";

// Append to contents of 'b'
b += "ello";
// When you set the variable's b value to "hello", 
// this would result in changing the pointer
// to the object in the HEAP the variable "a" is already pointing to
// Result would be: (reference of a == reference of b) --> TRUE
// b = "hello"; 

Console.WriteLine(a == b);                       // value comparison
Console.WriteLine((object)a == (object)b);       // reference comparison
Console.WriteLine (object.ReferenceEquals(a,b)); // reference comparison without casting

Result:
True
False
False

Explanation:
This will create a new object:
string a = "hello";

This will create another object:
string b = "h"; 

This will create yet another object:
b += "ello";

The following will create a reference to an existing object, more precisely, it will point to the same object the variable "a" points to  →  "hello".
string c = "hello"; 
Console.WriteLine (object.ReferenceEquals(a,c)); // --> TRUE

Strings are immutable--the contents of a string object cannot be
  changed after the object is created, although the syntax makes it
  appear as if you can do this. For example, when you write this code,
  the compiler actually creates a new string object to hold the new
  sequence of characters, and that new object is assigned to b. The
  string "h" is then eligible for garbage collection.

A:

C# uses the == token to represent three distinct operators: an overloadable equality-check operator (usable on class types or value types if overloads exist for the exact types in question), a non-overloadable reference-identity-check operator (which requires that both operands be class references, and requires that the types not be mutually exclusive), and a null-check operator (which is usable with any class type, nullable value type, or generics that might be one of the above).  While most forms of overloading are defined in a uniform fashion across .NET languages, the use of one operator for all three kinds of equality is not.  Other languages like VB.NET use a different token for the first form (e.g. in VB.NET, the expression (x = y) uses an equality-test overload if one is defined, or generates a syntax error if not; (x Is y) tests whether x and y identify the same object instance without regard for whether an overloaded equality operator exists).
The purpose of the casts to Object is to ensure that the == token gets interpreted as representing a reference-identity-check operator rather than an overloadable equality operator; such casts are needed only because of how C implements the == operator, and would not be needed in other languages like VB.NET.

