巧合地为字符串对象分配与另一个字符串对象相同的文本,使得两者都无意中指向同一个对象。为什么?

时间:2017-06-20 05:34:19

标签: string vb.net object

请考虑以下代码段,尤其是适用于Iss1的{​​{1}}运算符的注释。

s2

Dim s1 As String = "1" Dim s2 As String = "2" Debug.Print((s1 Is s2).ToString) 'False - as expected s1 = s2 Debug.Print((s1 Is s2).ToString) 'True - as expected s1 = "3" Debug.Print((s1 Is s2).ToString) 'False - as expected s2 = "3" Debug.Print((s1 Is s2).ToString) 'True - wth? s2 = "4" Debug.Print((s1 Is s2).ToString) 'False - as expected 分配会暂时使s2 = "3"s1个相同的对象生效。这背后的理由是什么?这不是有潜在危险吗?

1 个答案:

答案 0 :(得分:3)

正在发生的事情被称为String interning

由于字符串是不可变的,因此.NET运行时将您创建的字符串对象存储在表中以节省内存。每当你声明一个纯(,如声明而不对其执行任何操作)字符串in-code时,它将检查该字符串是否被实现。如果是,则.NET运行时将引用实例化实例,而不是创建一个全新实例。

请参阅String.IsInterned() method

  

公共语言运行库自动维护一个名为 intern pool 的表,其中包含 的单个实例,在程序中声明的每个唯一文字字符串常量 < / em>,以及通过调用Intern方法以编程方式添加的任何唯一String实例。

例如:

Dim s1 As String = "a string" 'A pure, constant string.
Dim s2 As String = s1
Dim s3 As String = "this is " & s1 'Not pure: performing string concatenation.
Dim s4 As String = "this is a string"

Console.WriteLine("s1: " & s1)
Console.WriteLine("s2: " & s2)
Console.WriteLine("s3: " & s3)
Console.WriteLine("s4: " & s4)

Console.WriteLine("s1 Is s2: " & (s1 Is s2)) 'True
Console.WriteLine("s3 Is s4: " & (s3 Is s4)) 'False, s3 has not been interned and is its own instance.

在线测试:http://ideone.com/YtkLTz