简体   繁体   中英

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?

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".

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.

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 (eg 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.

Comment with Code

So if the values “xx” were set at runtime all to the same value of “xx” then you would get different result of false since the compiler did not have a chance to do the optimization at runtime, even though it is the same code and input values in both cases, different results for precompiled vs runtime.

private void button1_Click(object sender, EventArgs e)
{
    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
}

private void button2_Click(object sender, EventArgs e)
{
    string a = textBox1.Text; //type in xx at runtime
    string b = textBox2.Text; //type in xx at runtime
    string c = textBox3.Text; //type in just "x" at runtime
    string d = String.Intern(c + c);

    Console.WriteLine((object)a == (object)b); // False with runtime values that have the same value
    Console.WriteLine((object)a == (object)d); // False 
    Console.WriteLine(a == d); // True - the Equals Operator of the string works as expected still 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM