変数を含むstring.formatとインライン変数


9

使用する長所/短所(ある場合)は何ですか

string output; 
int i = 10;
output = string.Format("the int is {0}", i);

string output; 
int i = 10;
output = "the int is " + i;

私は常に後者の例を使用してきましたが、オンラインチュートリアルの大部分がstring.formatの例を使用しているようです。効率に関して実際の違いはないと思います。私の最初の考えは、変数を挿入するためにコーダーが文字列を分割し続ける必要がないようにすることです。


8
主な理由は、プログラムがさまざまな言語が文章を構築する方法を理解する必要がないため、翻訳がはるかに簡単になることです。たとえば、フランス語の表現やフレーズの多くは、英語の翻訳に比べて前から後ろに向かっています。
JohnL、2012年

回答:


22

プロジェクトで翻訳が重要であると考える場合、最初の構文が実際に役立ちます。

たとえば、次のような場合があります。

static final string output_en = "{0} is {1} years old.";
static final string output_fr = "{0} a {1} ans.";

int age = 10;
string name = "Henri";
System.out.println(string.Format(output_en, name, age));
System.out.println(string.Format(output_fr, name, age));

また、変数が文の同じ場所にあるとは限らないことにも注意してください。

static final string output_yoda = "{1} years {0} has.";

4
オブジェクト主語動詞構文の例としてヨーダ語を使用する場合は+1。
Mike Harris

1
:C#で、私たちは、新しいオプション持っているSystem.out.println($"{name} is {age} year's old.");
Berin Loritsch


@BerinLoritsch:残念ながら、ローカリゼーションにはまったく使用できません。
ブライアンベッチャー2017

@BryanBoettcherは理解しましたが、OPでそれが彼らが達成しようとしていたことを言っているのを見ませんでした。
Berin Loritsch

8

/programming/4671610/why-use-string-formatの最初の回答を確認してください。それはなぜそれが良いのかについて私の意見のすべてをカバーしています。

また、各.NETアセンブリには、一意の文字列のコレクションを含むインターンプールがあります。コードがコンパイルされると、コードで参照するすべての文字列リテラルがこのプールに追加されます。次のようなコードがある場合:

"the int is " + i + " and the double is " + d

これにより、プールで2つの文字列になります。

あなたが持っている場合:

"the int is {0} and the double is {1}"

プールにはストリングが1つだけあります。

文字列がインターンされるときとそうでないときを知るのは少し複雑です。ときどきインターンする必要がないかもしれない文字列を検出するときにコンパイラーがある程度のインテリジェンスを持っているためです... これについてより多くの洞察を与えるこの記事の例をチェックしてください案件。

編集:少し掘り下げた後、私は質問に対する興味深い答えに遭遇しました。要するに、+ 30票の回答の作成者は、ローカリゼーションが関与していない場合、文字列連結を支持する説得力のある議論をします。


2
私はまた、文体的には、cからprintfやsprintfに慣れている私のような人々と共鳴します。
ジョナサンヘンソン2012年

私は自分の答えを修正するためになぜ反対票を投じたか知りたいと思いました。ありがとう。
Jalayn、2012年

4

出力時に文字列がどのように表示されるかを正確に確認できるため、最初の方法を使用します。スペースを追加することを忘れたり、文字列を追加するだけでスペースを追加したりするのは非常に簡単です。

追加の文字列を作成する必要がないため、最初の方法にはパフォーマンス上の利点もあると思います。しかし、それは私の主な関心事ではありません。


2

最初のオプションを使用することで、一般的に使用されるフォーマット文字列を保存し、必要な入力を減らすことができ、使用されているすべての場所で文字列を簡単に更新できます。基本的に、最初のオプションでは、DRYを簡単に実装できます。あなたが述べたように、複数の変数を文字列で使用する必要がある場合、それはより良い構文でもあります。


ああ、わかりました。例は考えていなかったと思います。string.format( "intは{0}です。ここでも{0}"、int);
ジム、

1

string.Format()結果が正確にどうなるかを確認するのが簡単になると思います(そのため、忘れられたスペースなどに問題がないので)、タイプや変更も簡単です。

非常に単純な書式設定を行う場合は、+plus演算子を使用する方が簡単かもしれませんが、2つの文字列を連結する場合にのみ使用する傾向があります。

どのように表示するにstring.Format()行くから:修正する方が簡単です、あなたはあなたの例では、文の最後に完全に停止を追加したいと考えるstring.Format("The int is {0}", i)のはstring.Format("The int is {0}.", i)ちょうど1つの文字です。しかし、から"the int is " + iへ行くこと"the int is " + i + '.'ははるかに多いです。

のもう1つの利点はstring.Format()、のように、使用する形式を簡単に指定できることですstring.Format("The int is 0x{0:X}.", i)。これは、日付をフォーマットするときにさらに重要です。

効率に関してstring.Format()は、おそらく単純な文字列の連結よりも遅くなります。しかし、このようなコードはホットパス上にない可能性が高いため、問題ではありません。そしてもしそうなら、あなたはおそらくを使用する方が良いでしょうStringBuilder


とにかくstring.Formatは内部的にStringBuilderを使用します
Bryan Boettcher

1

コードを最も読みやすくするものを使用してください。パフォーマンスについて心配する必要はありません。

以下の例では、Bの方が読みやすいので、Bを選択します。しかし、上記の言語翻訳も意味があります。誰かに強制的にstring.Formatを使用させないでください。代わりに、The Sad Tragedy of Micro Optimizations Theaterの Jeff Atwoodsの優れたブログを読んでください。

A:

string output; 
int i = 10;
output = string.Format("the int is {0}", i);

B:

string output; 
int i = 10;
output = "the int is " + i;

-1

参照:文字列出力:フォーマットまたはC#での連結?

このコードを検討してください。

これは、コードを少し変更したバージョンです。

  1. 私がConsole.WriteLineを削除したのは、測定しようとしているものよりも数桁遅いためです。
  2. ループの前にストップウォッチを開始し、直後に停止します。これにより、関数の実行にたとえば26.4ティックを使用しても精度が失われません。
  3. 結果を反復回数で分割する方法が間違っていました。1000ミリ秒と100ミリ秒がある場合、どうなるかを確認してください。どちらの場合も、1000000で除算した後、0ミリ秒になります。
Stopwatch s = new Stopwatch();

var p = new { FirstName = "Bill", LastName = "Gates" };

int n = 1000000;
long fElapsedMilliseconds = 0, fElapsedTicks = 0, cElapsedMilliseconds = 0, cElapsedTicks = 0;

string result;
s.Start();
for (var i = 0; i < n; i++)
    result = (p.FirstName + " " + p.LastName);
s.Stop();
cElapsedMilliseconds = s.ElapsedMilliseconds;
cElapsedTicks = s.ElapsedTicks;
s.Reset();
s.Start();
for (var i = 0; i < n; i++)
    result = string.Format("{0} {1}", p.FirstName, p.LastName);
s.Stop();
fElapsedMilliseconds = s.ElapsedMilliseconds;
fElapsedTicks = s.ElapsedTicks;
s.Reset();


Console.Clear();
Console.WriteLine(n.ToString()+" x result = string.Format(\"{0} {1}\", p.FirstName, p.LastName); took: " + (fElapsedMilliseconds) + "ms - " + (fElapsedTicks) + " ticks");
Console.WriteLine(n.ToString() + " x result = (p.FirstName + \" \" + p.LastName); took: " + (cElapsedMilliseconds) + "ms - " + (cElapsedTicks) + " ticks");
Thread.Sleep(4000);

それらは私の結果です:

1000000 x result = string.Format("{0} {1}", p.FirstName, p.LastName); took: 618ms - 2213706 ticks
1000000 x result = (p.FirstName + " " + p.LastName); took: 166ms - 595610 ticks

1
これは、最初のコード例または2番目のコード例の方が優れた設計であるかどうかの側面にどのように答えますか?これが人にとって維持しやすいコードであるかどうか、100万回以上の0.5秒はどのように説明されますか?

ジムは「長所と短所は何ですか?」と尋ねました。これは、多くの反復で、String.Formatの方が高速であることを示しています。
jp2code、2015年

コードのブロックとして残したり、OPのコードとの違いを残したりするのではなく、それを回答に完全に追加することを検討してください。現状では、あなたの答えはOPの英語の質問には答えません。他の答えを見てください。それらからすべてのコードを削除し、それでもOPの質問に対する回答を得ることが可能です。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.