代码之家  ›  专栏  ›  技术社区  ›  babybob

转换为“对象”类型的目的是什么?

  •  19
  • babybob  · 技术社区  · 8 年前

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

     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本身就是字符串的对象,那么再次转换为对象类型的目的是什么?

    4 回复  |  直到 8 年前
        1
  •  24
  •   Community Mike Kinghan    7 年前

    C#编译器将尝试在编译时获取所有常量字符串。这就是所谓的 字符串驻留 因此,在生成代码之后 a b 其中包含“xx”。

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

    另一件事是 strings are immutable 在.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
    

    那么为什么是 Console.WriteLine((object)a == c); 做参考检查??因为编译器将选择 == 检查引用相等性的对象上的运算符。


    因此,在你的问题中,向对象转换的整个要点是检查字符串实例化是否有效。 假设编译时没有实训 .

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

    Console.WriteLine((object)a == (object)b); 会打印“False”,因为 b 两个人 不同的字符串 在内存中,两者看起来都像“xx”。

        2
  •  6
  •   Legends pawelglow    8 年前

    所提供答案的补充: string (C# Reference)

    这个 系统String类是不可变的引用类型 提供于 .NET框架类库。此类创建新字符串 这种类型的对象不会改变,尽管语法使它 看起来好像内容可以更改。此外,字符串用作 哈希表键用于计算哈希值,以避免 破坏哈希数据结构。

    例子:

    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”指向的同一对象→ “你好”。

    string c = "hello"; 
    Console.WriteLine (object.ReferenceEquals(a,c)); // --> TRUE
    

    字符串是不可变的-- 字符串对象的内容不能是 创建对象后更改 ,尽管语法决定了 看起来好像你能做到这一点。例如,当您编写此代码时, 编译器实际上创建了一个新的字符串对象来保存新的 字符序列,新对象被分配给b 字符串“h”就可以进行垃圾收集。

        3
  •  5
  •   supercat    8 年前

    C#使用 == 表示三个不同运算符的标记:可重载的相等检查运算符(如果所讨论的确切类型存在重载,则可用于类类型或值类型)、非可重载的引用标识检查运算符(这要求两个操作数都是类引用,并且要求类型不相互排斥),和null检查运算符(可用于任何类类型、可为null的值类型或可能是上述类型之一的泛型)。虽然在.NET语言中,大多数形式的重载都是以统一的方式定义的,但对所有三种类型的等式使用一个运算符却不是。其他语言(如VB.NET)对第一个表单使用不同的标记(例如,在VB.NET中,表达式 (x = y) 如果定义了相等测试重载,则使用相等测试重载;如果未定义,则生成语法错误; (x Is y) x y 标识同一对象实例,而不考虑是否存在重载的相等运算符)。

    强制转换的目的是 Object 是确保 == 标记被解释为表示引用标识检查运算符,而不是可重载的相等运算符;只因为C是如何实现 == 运算符,在其他语言(如VB.NET)中不需要。

        4
  •  1
  •   Sql Surfer    8 年前

    带代码的注释

    因此,如果在运行时将值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 
    }
    
    推荐文章