79

これは非常にばかげた質問だと思いますが、何かが足りないに違いありません。

なぜString.Copy(string)を使いたいのでしょうか?

ドキュメントには方法が記載されています

指定された文字列と同じ値で文字列の新しいインスタンスを作成します。

文字列は.NETで不変であるため、このメソッドを使用する利点が何であるかはわかりません。

 string copy = String.Copy(otherString);

すべての実用的な目的のためにと同じ結果をもたらすように思われる

 string copy = otherString;

つまり、内部で行われている簿記と、コピーがReferenceEqualsotherStringにないという事実を除いて、観察可能な違いはありません。Stringは、同一性ではなく値に基づいた不変のクラスです。(@Andrew Hareのおかげで、私の元の言い回しは、ingとnotの間に違いがあることに気付いたが、有用なCopy違いがないと認識されていることを懸念するほど正確ではなかったと指摘してくれました。)

もちろん、null引数が渡されると、CopyはをスローしArgumentNullException、「新しいインスタンス」はより多くのメモリを消費する可能性があります。後者はほとんどメリットとは思えず、nullチェックがCopyメソッド全体を保証するのに十分なボーナスであるかどうかはわかりません。

ありがとう。

4

9 に答える 9

51

実際にString.Copyは、新しいメモリを割り当て、ある文字列から別の文字列に文字をコピーしています。両方の変数を同じインスタンスにするのではなく、完全に新しいインスタンスを取得します。これは、メモリの場所を直接処理し、文字列を変更できるアンマネージ コードで文字列を使用する場合に問題になる可能性があります。

于 2009-02-06T16:18:46.950 に答える
26

ここにパズルの 1 ピースがあります。なぜそれをしたいのか説明していませんが、機能的な違いを説明するのに役立ちます.

キーワードを使用して文字列を固定するfixedと、内容が変更可能になります。私の頭の上では、あなたがこれをやりたいと思うような状況は思いつきませんが、それは可能です。

string original = "Hello World";
string refCopy = original;
string deepCopy = String.Copy(original);

fixed(char* pStr = original)
{
   *pStr = 'J';
}

Console.WriteLine(original);
Console.WriteLine(refCopy);
Console.WriteLine(deepCopy);

出力:

Jello World
Jello World
Hello World
于 2009-02-06T19:16:56.713 に答える
21

String.Copynew を返し、Stringと同じ結果は得られません

String copy = otherString;

これを試して:

using System;

class Program
{
    static void Main()
    {
        String test = "test";
        String test2 = test;
        String test3 = String.Copy(test);

        Console.WriteLine(Object.ReferenceEquals(test, test2));
        Console.WriteLine(Object.ReferenceEquals(test, test3));

        Console.ReadLine();
    }
}

これらの参照を設定test2 = testすると、同じString. この関数は、内容は同じですが、ヒープ上の別のオブジェクトとして新しい参照をCopy返します。String


編集:私がOPの質問に答えなかったことにかなり怒っている人がたくさんいます. 質問自体の誤った前提を修正することで、質問に答えたと思います。これは、私の要点をうまく説明する類似の (過度に単純化されていない場合) 質問と回答です。

質問:

私の車には、車の両側に 1 つずつ、合計 2 つのドアがあることに気付きました。どのドアを使っても運転席に座ってしまうのは事実だと思います。他のドアの目的は何ですか?

答え:

実際、どちらのドアを使用しても運転席に座れるというわけではありません。運転席側のドアを使用すると運転席に、助手席側のドアを使用すると助手席になります。

この例では、質問が「助手席側のドアの目的は何ですか?」であるため、答えは実際には答えではないと主張できます。しかし、その質問はドアがどのように機能したかについての誤解に完全に基づいていたので、前提の反駁は演繹によって他のドアの目的に新たな光を当てるということにはなりませんか?

于 2009-02-06T16:16:16.267 に答える
9

.NET 4.0 の BCL をすばやく検索すると、このstring.Copyメソッドが約 6 か所で呼び出されていることがわかります。用途は、おおよそ次のカテゴリに分類されます。

  1. 渡された文字列を損傷する可能性があるネイティブ関数との相互運用用。P/Invoke 宣言に影響を与えることができず、呼び出されている関数を修正できない場合string.Copyは、最適な選択です。

  2. パフォーマンス上の理由で文字列がその場で変更される状況。潜在的に長い文字列で数文字だけを小文字に変換する必要がある場合、文字列を 2 回コピーして追加のガベージを作成せずに変換する唯一の方法は、文字列を変更することです。

  3. 必要がないと思われる場所で。一部のプログラマーは、Java または C++ の文字列に慣れていて、C# で文字列をコピーすることがほとんど役に立たないことに気付いていない可能性があります。

于 2011-07-03T05:01:25.693 に答える
8
string a = "abc";
string b = String.Copy(a);

Monitor.Enter(a); // not the same as Monitor.Enter(b);

でも

string c = "123";
string d = c;
Monitor.Enter(c); // the same as Monitor.Enter(d);

誰もが気にする方法については、完全を期すためにあると思います。


また

StringBuilder sb = new StringBuilder(100);
sb.Append("abc");
string a = sb.ToString();
string b = String.Copy(a);

が作成したサイズ 100 のバッファを指すため、aそれよりも多くの RAM を使用すると思います。(メソッドの内部を見てください)baStringBuilderStringBuilder.ToString()


.NET フレームワークStringBuilderを利用し、その一部になることで、.NET ファイルの内容が変わると思います。したがって、 aは必ずしも不変ではありません。String.Copy()StringBuilderstringstring

于 2009-02-06T16:26:44.827 に答える
0
string a = "test";
string b = a;
//Object.ReferenceEquals(a,b) is true
a += "more";
//Object.ReferenceEquals(a,b) is now false !

自動変更検出?

于 2009-02-06T16:50:03.687 に答える