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に対するシステムの参照 (インターンされている場合)。それ以外の場合は、strの値を持つ文字列への新しい参照。
例外
str は nullです。
例
次の例では、値が等しい 2 つの文字列を作成し、それらの文字列を挿入すると同じ参照が生成されることを示します。
// 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は、等しい値を持つ 2 つの文字列が同じインターン参照を返すように保証しますが、返される参照が文字列リテラルと同じであることを保証しません。
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.
パフォーマンスに関する考慮事項
アプリケーションが割り当てるメモリの合計量を減らそうとしている場合は、文字列をインターンすると 2 つの望ましくない副作用があることに注意してください。 まず、共通言語ランタイム (CLR) が終了するまで、強制 String オブジェクトに割り当てられたメモリは解放されない可能性があります。 その理由は、強制 String オブジェクトに対する CLR の参照は、アプリケーションまたはアプリケーション ドメインが終了した後も保持される可能性があるということです。 次に、文字列をインターン化するには、まず文字列を作成する必要があります。 String オブジェクトによって使用されるメモリは、最終的にはガベージ コレクションされるとしても、割り当てられる必要があります。
CompilationRelaxations.NoStringInterning列挙メンバーは、アセンブリを文字列リテラルのインターンを必要としないものとしてマークします。 既定では、C# コンパイラはパフォーマンスを向上させるために各アセンブリに CompilationRelaxationsAttribute フラグを持つNoStringInterningを出力します。つまり、文字列リテラルがインターン プールに追加される保証はありません。 NoStringInterning属性を使用して、アセンブリのCompilationRelaxationsAttributeをカスタマイズできます。
ネイティブ AOT を使用してアプリを発行する場合、NoStringInterningをオフにすることはサポートされていません。 ネイティブ AOT では、文字列リテラルがインターン プールに追加されるとは限らないので、 Intern ソース コード内のリテラルと思われる文字列の一致が見つからない可能性があります。