String.Intern(String) 方法
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
检索系统对指定 String对象的引用。
public:
static System::String ^ Intern(System::String ^ str);
public static string Intern(string str);
static member Intern : string -> string
Public Shared Function Intern (str As String) As String
参数
- str
- String
在实习生池中搜索的字符串。
返回
如果系统被实习生所引用,则为系统引用
例外
str 是 null。
示例
以下示例创建两个值相等的字符串,并演示它们之间的交错会产生相同的引用。
// Sample for String.Intern(String)
using System;
using System.Text;
class Sample
{
public static void Main()
{
string s1 = new StringBuilder().Append("My").Append("Test").ToString();
string s2 = new StringBuilder().Append("My").Append("Test").ToString();
Console.WriteLine($"s1 == {s1}");
Console.WriteLine($"s2 == {s2}");
Console.WriteLine($"Are s1 and s2 equal in value? {s1 == s2}");
Console.WriteLine($"Are s1 and s2 the same reference? {Object.ReferenceEquals(s1, s2)}");
string i1 = String.Intern(s1);
string i2 = String.Intern(s2);
Console.WriteLine($"After interning:");
Console.WriteLine($" Are i1 and i2 equal in value? {i1 == i2}");
Console.WriteLine($" Are i1 and i2 the same reference? {Object.ReferenceEquals(i1, i2)}");
}
}
/*
This example produces the following results:
s1 == MyTest
s2 == MyTest
Are s1 and s2 equal in value? True
Are s1 and s2 the same reference? False
After interning:
Are i1 and i2 equal in value? True
Are i1 and i2 the same reference? True
*/
// Sample for String.Intern(String)
open System
open System.Text
let s1 = StringBuilder().Append("My").Append("Test").ToString()
let s2 = StringBuilder().Append("My").Append("Test").ToString()
printfn $"s1 = {s1}"
printfn $"s2 = {s2}"
printfn $"Are s1 and s2 equal in value? {s1 = s2}"
printfn $"Are s1 and s2 the same reference? {Object.ReferenceEquals(s1, s2)}"
let i1 = String.Intern s1
let i2 = String.Intern s2
printfn "After interning:"
printfn $" Are i1 and i2 equal in value? {i1 = i2}"
printfn $" Are i1 and i2 the same reference? {Object.ReferenceEquals(i1, i2)}"
(*
This example produces the following results:
s1 = MyTest
s2 = MyTest
Are s1 and s2 equal in value? True
Are s1 and s2 the same reference? False
After interning:
Are i1 and i2 equal in value? True
Are i1 and i2 the same reference? True
*)
Imports System.Text
Class Sample
Public Shared Sub Run()
Dim s1 As String = New StringBuilder().Append("My").Append("Test").ToString()
Dim s2 As String = New StringBuilder().Append("My").Append("Test").ToString()
Console.WriteLine($"s1 = {s1}")
Console.WriteLine($"s2 = {s2}")
Console.WriteLine($"Are s1 and s2 equal in value? {s1 = s2}")
Console.WriteLine($"Are s1 and s2 the same reference? {s1 Is s2}")
Dim i1 As String = String.Intern(s1)
Dim i2 As String = String.Intern(s2)
Console.WriteLine("After interning:")
Console.WriteLine($" Are i1 and i2 equal in value? {i1 = i2}")
Console.WriteLine($" Are i1 and i2 the same reference? {i1 Is i2}")
End Sub
End Class
'
's1 = MyTest
's2 = MyTest
'Are s1 and s2 equal in value? True
'Are s1 and s2 the same reference? False
'After interning:
' Are i1 and i2 equal in value? True
' Are i1 and i2 the same reference? True
'
注解
![注意] > 虽然
String.Intern保证两个值相等的字符串返回相同的实习生引用,但它不保证返回的引用与字符串文本相同。
The common language runtime maintains a table, called the *intern pool*, that holds a single reference for each unique string value. The <xref:System.String.Intern*> method uses the intern pool to search for a string equal to the value of `str`. If no such string exists, a reference to `str` is added to the pool, and that reference is returned. (In contrast, the <xref:System.String.IsInterned(System.String)> method returns a null reference if the requested string doesn't exist in the intern pool.)
运行时可以使用实习生池来节省字符串存储。 但是,无法保证字符串文本的自动插入 -- 根据程序集的编译和执行方式,某些文本可能不会添加到池中。
在以下示例中,字符串 s1 的值为“MyTest”。 该 System.Text.StringBuilder 类生成一个新的字符串对象,其值与 s1 相同。 将该字符串的引用分配给s2。 该方法Intern搜索与s2值相同的字符串。 如果s1已驻留(例如,因为程序集需要字符串字面量驻留),该方法将返回与s1相同的引用,然后将该引用分配给s3,然后s1和s3进行比较以验证相等性。 否则,将为s2创建一个新的驻留条目并将其分配给s3,而s1与s3比较不相等。 在任一情况下, s1 并 s2 比较不相等,因为它们引用不同的对象。
string s1 = "MyTest";
string s2 = new StringBuilder().Append("My").Append("Test").ToString();
string s3 = String.Intern(s2);
Console.WriteLine((Object)s2==(Object)s1); // Different references.
Console.WriteLine((Object)s3==(Object)s1); // The same reference.
let s1 = "MyTest"
let s2 = StringBuilder().Append("My").Append("Test").ToString()
let s3 = String.Intern s2
printfn $"{s2 :> obj = s1 :> obj}" // Different references.
printfn $"{s3 :> obj = s1 :> obj}" // The same reference.
Dim s1 As String = "MyTest"
Dim s2 As String = New StringBuilder().Append("My").Append("Test").ToString()
Dim s3 As String = String.Intern(s2)
Console.WriteLine(CObj(s2) Is CObj(s1)) ' Different references.
Console.WriteLine(CObj(s3) Is CObj(s1)) ' The same reference.
性能注意事项
如果您尝试减少应用程序分配的内存总量,请记住,驻留字符串会产生两个不良的副作用。 首先,在公共语言运行库(CLR)终止之前,为驻留 String 对象分配的内存通常不会被释放。 原因是 CLR 对驻留对象 String 的引用可能在您的应用程序甚至应用程序域终止后仍然存在。 其次,要在内存中驻留字符串,必须先创建字符串。 使用String对象的内存仍必须进行分配,即使该内存最终会被垃圾回收。
CompilationRelaxations.NoStringInterning 枚举成员将程序集标记为不需要字符串文字驻留。 默认情况下,C# 编译器在每个程序集上发出一个 CompilationRelaxationsAttribute 带有 NoStringInterning 标志的标志,以提高性能,这意味着不能保证将字符串文本添加到实习生池。 可以使用NoStringInterning特性对程序集CompilationRelaxationsAttribute进行自定义。
使用 本机 AOT 发布应用时,不支持关闭 NoStringInterning 。 使用本机 AOT 时,无法保证将字符串文本添加到实习生池,因此 Intern 可能无法找到与源代码中似乎是文本的字符串匹配项。