6

C# で型の変数を作成したい場合は、string次を使用できます。

string str="samplestring"; // this will allocate the space to hold the string

C# では、stringはクラス型であるため、オブジェクトを作成する場合は通常、newキーワードを使用する必要があります。newでは、 orなしで割り当てはどのように行われるのconstructorsでしょうか?

4

7 に答える 7

8

あなたが書くとき

string str="samplestring";

コンパイラは2つの命令を生成します。

  1. まず、ldstrメタデータから文字列リテラルを取得します。必要な量のメモリを割り当てます。新しいStringオブジェクトを作成し、そのオブジェクトへの参照をスタックにプッシュします。
  2. 次にstloc(またはその短縮形の1つ、たとえばstloc.0)は、その参照をローカル変数に格納しますstr

ldstrこれにより、文字のシーケンスごとに1回だけメモリが割り当てられることに注意してください。

したがって、以下の例では、両方の変数がメモリ内の同じオブジェクトを指します。

// CLR will allocate memory and create a new String object
// from the string literal stored in the metadata
string a = "abc";

// CLR won't create a new String object. Instead, it will look up for an existing
// reference pointing to the String object created from "abc" literal
string b = "abc";

このプロセスは、文字列インターンとして知られています。

また、ご存知のように、.NETでは文字列は不変です。したがって、Stringオブジェクトの作成後にオブジェクトの内容を変更することはできません。つまり、文字列を連結するたびに、CLRは新しいStringオブジェクトを作成します。

たとえば、次のコード行です。

string a = "abc";
string b = a + "xyz";

次のILにコンパイルされます(もちろん、正確ではありません)。

  1. ldstrメモリを割り当て、リテラルから新しいStringオブジェクトを作成します"abc"
  2. stlocそのオブジェクトへの参照をローカル変数に格納しますa
  3. ldlocその参照をスタックにプッシュします
  4. ldstrメモリを割り当て、リテラルから新しいStringオブジェクトを作成します"xyz"
  5. callSystem.String::Concatスタック上のこれらのStringオブジェクトでを呼び出します
  6. の呼び出しはSystem.String::Concat、数十のIL命令と内部呼び出しに分解されます。つまり、両方の文字列の長さをチェックし、連結結果を格納するために必要な量のメモリを割り当ててから、それらの文字列を新しく割り当てられたメモリにコピーします。
  7. stloc新しく作成された文字列への参照をローカル変数に格納しますb
于 2012-10-19T15:44:13.777 に答える
6

これは、文字列リテラルを許可することでショートカットを提供する C# コンパイラにすぎません。

必要に応じて、任意の数の異なるコンストラクターで文字列をインスタンス化できます。例えば:

 char[] chars = { 'w', 'o', 'r', 'd' };
 string myStr = new String(chars);
于 2012-10-19T14:35:26.273 に答える
3

MS のドキュメントによると、デフォルトの文字列コンストラクターを使用するために新しいコマンドを使用する必要はありません。

ただし、これは機能します。

char[] letters = { 'A', 'B', 'C' };
string alphabet = new string(letters);

c# 文字列 (MSDN プログラミング ガイドより)

于 2012-10-19T14:34:40.933 に答える
2

文字列は実際には参照型です。変数は、メモリ内の値への参照を保持します。したがって、値ではなく参照をオブジェクトに割り当てるだけです。Pluralsight のこのビデオをご覧になることをお勧めします (14 日間の無料試用版を入手できます)。

Pluralsight C# の基礎 - 文字列

免責事項: 私は Pluralsight とは一切関係ありません。私はサブスクライバーで、向こうのビデオが大好きです

于 2012-10-19T14:40:36.097 に答える
1

.net ではすべてがオブジェクトですが、インスタンス化を必要としないプリミティブ型 (int、bool など) がまだあります。ここでわかるように、文字列は、最大 2GB まで拡張できるベクトル/配列構造を指す 4 バイトのアドレス ref です。文字列は変更できない型であるため、文字列を変更するときは既存の変数を編集するのではなく、リテラル値に新しいメモリを割り当ててから、文字列ポインタを新しいメモリ構造を指すように変更します。それが役立つことを願っています

于 2012-10-19T14:33:04.590 に答える
0

内部的にリテラルを使用して文字列を作成すると、アセンブリが NoStringInterning フラグでマークされているかどうかに応じて、次のようになります。

String str = new String("samplestring");
// or with NoStringInterning
String str = String.Intern("samplestring");
于 2012-10-19T15:00:56.797 に答える
-4

あなたがそのような何かを書くならば、Javaで:

String s1 = "abc";
String s2 = "abc";

メモリはいわゆる文字列プールの「abc」に割り当てられ、s1とs2の両方がそのメモリを参照します。そして、s1 == s2はtrueを返します( "=="は参照を比較します)。しかし、あなたが書く場合:

String s1 = new String("abc");
String s1 = new String("abc");

s1==s2はfalseを返します。C#でも同じだと思います。

于 2012-10-19T14:38:48.267 に答える