5

私は次のC#コードを持っています:

string stg1 = "String 1";
string stg2 = "String 2";
string stg3 = "String 3";
string stg4;
stg4 = stg1 + stg3;
stg4 = stg4 + stg2 + stg3;
stg4 = "";
stg3 = "";

いくつの文字列オブジェクトが作成されますか?、、、、、、、、、の7つの文字列オブジェクトが作成されていると
思います。4番目のステートメント()が文字列オブジェクトを作成するかどうかはわかりませんでした。文字列に空の文字列を割り当ててもオブジェクトは作成されないことをどこかで読みましたが、それは本当ではないと思います。皆さんはどう思いますか?"String 1""String 2""String 3"stg1 + stg3stg4 + stg2 + stg3""""string stg4;""

4

2 に答える 2

11

文字列に空の文字列""を割り当ててもオブジェクトは作成されないことをどこかで読みましたが、それは真実ではないと思います。皆さんはどう思いますか?

それは完全に真実ではありません。空の文字列用に作成された文字列インスタンスが確実に存在します。

そうは言っても、そのコードには2つのインスタンスはありません。1つだけになります。コンパイル時に設定を無効にしない限り、コンパイラは、同一のすべてのコンパイル時リテラル文字列を検索し、stringそれを表す1つのオブジェクトのみを作成し、その文字列を定義したすべての変数にその1つの文字列への同じ参照を与えます。これは「インターン」と呼ばれます。

デフォルトでは、文字列インターンはコンパイル時のリテラル文字列に対してのみ実行され、実行時に生成される文字列に対しては実行されないことに注意してください。実行時に、等しい2つの文字列を生成する場合、それらは必ずしも同じ文字列オブジェクトへの参照であるとは限りません。

それ以外は、あなたの分析は正しいです。

また、文字列が1つだけ作成されることを正しく述べている間stg4 + stg2 + stg3は、その理由を実際に説明していなかったことにも注意してください。その理由は明らかではありません。

最初の推測では、ここで2つの操作が実行されます。最初stg4 + stg2は文字列になり、次にその結果を連結しstg3て最終結果を作成します。しかし、そうではありません。コンパイラは実際にはへの単一の呼び出しを生成し、string.Concat3つの文字列すべてを引数として渡し(任意の数の文字列を受け入れることができるようにConcat定義されています) 、n-1中間体の文字列を作成するのではなく、1つの文字列だけを作成するのに十分賢いです値。Concat(params string[] args)Concat

于 2013-02-23T00:10:11.770 に答える
6

Servyの答えはかなり的確です。私は特に連結の正しい分析が好きです。

私はその優れた答えに1つの小さな追加のポイントを追加します。それは、非リテラルString.Emptyがリテラルにインターンされるかどうかが実装によって定義されるということです""。.NETのバージョンによっては、自動的にインターンするものとインターンしないものがあります。

見る

http://ericlippert.com/2009/09/28/string-interning-and-string-empty/

詳細については。

于 2013-02-23T00:47:59.370 に答える