转换为 "object" 类型的目的是什么?

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

我在一个网站上找到代码如下。

 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

这里a,b,d本身就是string的对象,又转成object类型的目的是什么?

C# 编译器将在编译时尝试获取所有常量字符串。这称为 string interning。因此,在代码生成后 ab 对包含 "xx" 的相同字符串 引用

您可以通过比较它们的引用来检查这一点(将它们转换为对象并进行相等性检查或使用 object.ReferenceEquals)。请记住,字符串的 == 运算符比较它们的值而不是它们的引用。

另一件值得一提的事情是.NET中的strings are immutable

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

那么为什么 Console.WriteLine((object)a == c); 要做背景调查??因为编译器会在检查引用相等性的对象上选择 == 运算符。


因此,在您的问题中转换为 object 的全部意义在于检查字符串实习是否有效。 假设在编译时没有实习发生

 string a = "xx";
 string b = "xx";
 string c = "x";
 string d = String.Intern(c + c);

然后 Console.WriteLine((object)a == (object)b); 会打印 "False",因为 ab 是两个 references内存中的不同字符串,两者看起来都像"xx".

对所提供答案的补充: 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.

示例:

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

结果:

True
False
False

说明:

这将创建一个新对象:

string a = "hello";

这将创建另一个对象:

string b = "h"; 

这将创建另一个对象:

b += "ello";

以下将创建对现有对象的引用,更准确地说,它将指向变量 "a" 指向的同一对象 → "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# 使用 == 标记来表示三个不同的运算符:一个可重载的相等性检查运算符(可用于 class 类型或值类型,如果所讨论的确切类型存在重载),一个不可重载的引用身份检查运算符(要求两个操作数都是 class 引用,并且要求类型不互斥),以及空值检查运算符(可用于任何 class 类型、可空值类型或可能是上述之一的泛型)。虽然大多数形式的重载都是在 .NET 语言中以统一的方式定义的,但对所有三种相等性使用一个运算符却并非如此。 VB.NET 等其他语言对第一种形式使用不同的标记(例如,在 VB.NET 中,表达式 (x = y) 如果已定义则使用相等测试重载,否则会生成语法错误; (x Is y) 测试 xy 是否标识相同的对象实例,而不考虑是否存在重载的相等运算符)。

转换为 Object 的目的是确保 == 标记被解释为表示引用身份检查运算符而不是可重载的相等运算符;仅由于 C 实现 == 运算符的方式才需要此类强制转换,而在 VB.NET.

等其他语言中则不需要

评论代码

因此,如果值“xx”在运行时都设置为相同的“xx”值,那么您将得到不同的 false 结果,因为编译器没有机会在运行时进行优化,即使在两种情况下都是相同的代码和输入值,预编译与运行时的结果不同。

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 
}