String.Intern(String) メソッド

定義

指定した 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

インターン プールから検索する文字列。

戻り値

String

str がインターン プールに存在する場合は、それに対するシステム参照。それ以外の場合は、値が str の文字列への新しい参照。

例外

strnullです。

次の例では、値が等しい 3 つの文字列を使用して、新しく作成された文字列とインターンされた文字列が等しいかどうかを判断します。

// Sample for String::Intern(String)
using namespace System;
using namespace System::Text;
int main()
{
   String^ s1 = "MyTest";
   String^ s2 = (gcnew StringBuilder)->Append( "My" )->Append( "Test" )->ToString();
   String^ s3 = String::Intern( s2 );
   Console::WriteLine( "s1 == '{0}'", s1 );
   Console::WriteLine( "s2 == '{0}'", s2 );
   Console::WriteLine( "s3 == '{0}'", s3 );
   Console::WriteLine( "Is s2 the same reference as s1?: {0}", s2 == s1 );
   Console::WriteLine( "Is s3 the same reference as s1?: {0}", s3 == s1 );
}

/*
This example produces the following results:
s1 == 'MyTest'
s2 == 'MyTest'
s3 == 'MyTest'
Is s2 the same reference as s1?: False
Is s3 the same reference as s1?: True
*/
// Sample for String.Intern(String)
using System;
using System.Text;

class Sample
{
    public static void Main()
    {
        string s1 = "MyTest";
        string s2 = new StringBuilder().Append("My").Append("Test").ToString();
        string s3 = String.Intern(s2);
        Console.WriteLine($"s1 == {s1}");
        Console.WriteLine($"s2 == {s2}");
        Console.WriteLine($"s3 == {s3}");
        Console.WriteLine($"Is s2 the same reference as s1?: {(Object)s2 == (Object)s1}");
        Console.WriteLine($"Is s3 the same reference as s1?: {(Object)s3 == (Object)s1}");
    }
}
/*
This example produces the following results:
s1 == MyTest
s2 == MyTest
s3 == MyTest
Is s2 the same reference as s1?: False
Is s3 the same reference as s1?: True
*/
// Sample for String.Intern(String)
open System
open System.Text

let s1 = "MyTest"
let s2 = StringBuilder().Append("My").Append("Test").ToString()
let s3 = String.Intern s2
printfn $"s1 = {s1}"
printfn $"s2 = {s2}"
printfn $"s3 = {s3}"
printfn $"Is s2 the same reference as s1?: {s2 :> obj = s1 :> obj}"
printfn $"Is s3 the same reference as s1?: {s3 :> obj = s1 :> obj}"
(*
This example produces the following results:
s1 = MyTest
s2 = MyTest
s3 = MyTest
Is s2 the same reference as s1?: False
Is s3 the same reference as s1?: True
*)
Imports System.Text

Class Sample

    Public Shared Sub Main()
        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($"s1 = {s1}")
        Console.WriteLine($"s2 = {s2}")
        Console.WriteLine($"s3 = {s3}")
        Console.WriteLine($"Is s2 the same reference as s1?: {s2 Is s1}")
        Console.WriteLine($"Is s3 the same reference as s1?: {s3 Is s1}")
    End Sub
End Class
'
's1 = MyTest
's2 = MyTest
's3 = MyTest
'Is s2 the same reference as s1?: False
'Is s3 the same reference as s1?: True
'

注釈

共通言語ランタイムは、プログラムで宣言またはプログラムで作成された各一意のリテラル文字列への単一の参照を含む、インターン プールと呼ばれるテーブルを維持することで、文字列ストレージを節約します。 そのため、特定の値を持つリテラル文字列のインスタンスは、システムに 1 回だけ存在します。

たとえば、複数の変数に同じリテラル文字列を割り当てると、ランタイムはインターン プールからリテラル文字列への同じ参照を取得し、各変数に割り当てます。

このメソッドでは Intern 、インターン プールを使用して、値 strと等しい文字列を検索します。 このような文字列が存在する場合は、インターン プール内の参照が返されます。 文字列が存在しない場合は、インターン プールに str 参照が追加され、その参照が返されます。

次の例では、"MyTest" という値を持つ文字列 s1 は、プログラム内のリテラルであるため、既にインターンされています。 このクラスは System.Text.StringBuilder 、s1 と同じ値を持つ新しい文字列オブジェクトを生成します。 その文字列への参照が s2 に割り当てられます。 このメソッドは Intern 、s2 と同じ値を持つ文字列を検索します。 このような文字列が存在するため、メソッドは s1 に割り当てられているのと同じ参照を返します。 その参照が s3 に割り当てられます。 参照s1とs2は異なるオブジェクトを参照しているため、比較は等しくありません。参照 s1 と s3 は、同じ文字列を参照するため、等しい比較を行います。

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.

このメソッドをメソッドと比較します IsInterned

バージョンに関する考慮事項

.NET Framework 3.5 Service Pack 1 では、空の文字列のインターンに関して、Internメソッドは .NET Framework 1.0 と 1.1 の動作に戻ります。 次の例では、変数str1Empty参照が割り当てられ、値が文字列に変換されたオブジェクトを変換StringBuilderした後にメソッドをEmpty呼び出Internすことによって返される参照がEmpty変数str2に割り当てられます。 次に、参照が str1 格納され str2 、等しいかどうかを比較します。

string str1 = String.Empty;
string str2 = String.Empty;

StringBuilder sb = new StringBuilder().Append(String.Empty);
str2 = String.Intern(sb.ToString());	

if((object)str1==(object)str2)
    Console.WriteLine("The strings are equal.");
else
    Console.WriteLine("The strings are not equal.");
let str1 = String.Empty
let str2 = String.Empty

let sb = StringBuilder().Append String.Empty
let str3 = String.Intern(string sb)

if (str1 :> obj) = (str3 :> obj) then
    printfn "The strings are equal."
else
    printfn "The strings are not equal."
Dim str1 As String = String.Empty
Dim str2 As String = String.Empty

Dim sb As StringBuilder = New StringBuilder().Append(String.Empty)
str2 = String.Intern(sb.ToString())	

If CObj(str1) Is CObj(str2) Then
    Console.WriteLine("The strings are equal.")
Else
    Console.WriteLine("The strings are not equal.")
End If

.NET Framework 2.0 Service Pack 1 と .NET Framework 3.0 では等 str1 str2しくありません。 他のすべてのバージョンでは、 str1 str2 同じです。

パフォーマンスに関する考慮事項

アプリケーションが割り当てるメモリの合計量を減らそうとしている場合は、文字列をインターンすると 2 つの望ましくない副作用があることに注意してください。 まず、共通言語ランタイム (CLR) が終了するまで、インターンされた String オブジェクトに割り当てられたメモリが解放されない可能性があります。 その理由は、アプリケーションまたはアプリケーション ドメインが終了した後も、CLR のインターン オブジェクト String への参照が保持される可能性があるということです。 次に、文字列をインターンするには、まず文字列を作成する必要があります。 オブジェクトによって String 使用されるメモリは、メモリが最終的にガベージ コレクションされる場合でも、引き続き割り当てる必要があります。

列挙メンバーは CompilationRelaxations.NoStringInterning 、アセンブリを文字列リテラルのインターン処理を必要としないものとしてマークします。 属性を使用してアセンブリにCompilationRelaxationsAttribute適用NoStringInterningできます。 また、 Ngen.exe (ネイティブ イメージ ジェネレーター) を使用して実行時の前にアセンブリをコンパイルする場合、文字列はモジュール間でインターンされません。

適用対象

こちらもご覧ください