2017-03-24 14 views
2

は考える:エスケープ文字アソシエC#6文字列補間

double price = 5.05; 
Console.Write($"{{Price = {price:C}}}"); 

と所望の出力:{価格= $ 5.05}

エスケープ「}」と最後の二つの波括弧を関連付ける方法はあり補間は意図どおりに機能するのですか?現状では、最初の二つは、(?Iが想定)エスケープされ、出力は{価格= C}

Console.Write($"{{Price = {price:C} }}"); 

期待どおりに動作しますが、余分なスペースを有します。そして、私は貧弱な男のソリューションと考えているテールブレースを連結することができます。口語訳が豊富な人の解答はありますか?ありがとう。

+0

私は「ああ!」と思った。ユニコードのエスケープシーケンス( '\ u007d'の'} ')を試してみましたが、私の前に言語デザイナーが来てCS8087を追加したようです - " A '}キャラクタは補間された'}} 'を2倍にしてのみエスケープできます文字列 " –

+0

同様の問題がString.Formatにあります:http://stackoverflow.com/a/15085178/121309、少なくともそれは一貫しています –

答えて

2

あなたはCONCATENATEの代わりに補間することができます - リテラル文字列として渡します

double price = 5.05; 
Console.Write($"{{Price = {price:C}{"}"}"); 
+5

それは...あまりよくないtbhですが、確かにそれは動作する必要があります –

+0

@ MarkGravell、私は同意、かなり。 'char'リテラルにすることができます。これは二重引用符の数を減らし、一重引用符を優先します...文字列補間構文を使用するという点では良いアイデアはありません...' StringBuilder'? :) – CoolBots

+2

通常の連結は 'stringBuilder'よりも効率的で、' string.Format'と同じです。 'StringBuilder'は未知数または多数の連結に最適です。固定少量ではなく、それほど多くはない –

0

さてあなたは、使用頻度の低いエスケープ文字を試すことができます。たぶん\ bは何も印刷せず、本当に長い間機能しなかったので動くでしょう。ような何か:

double price = 5.05; 
Console.Write($"{{Price = {price:C}\b}}"); 

それはあなたのために動作しない場合は、U + 200BまたはU + FEFFのような特別なUNICODE文字を試すことができます。

double price = 5.05; 
Console.Write($"{{Price = {price:C}\x8203}}"); 

エスケープ文字:https://blogs.msdn.microsoft.com/csharpfaq/2004/03/12/what-character-escape-sequences-are-available/

ユニコードの空白文字:https://www.cs.tut.fi/~jkorpela/chars/spaces.html

+2

素晴らしいですが、私は個人的には**ここで隠しキャラクターを使用することをおすすめしません - それはUIの奇妙さを含む下流の混乱を引き起こす可能性があります。それがOPのために働くならば、素晴らしい;しかし...個人的には、文字列の補間ではなく、別のアプローチを使用するようにC#を書き直しています。余分なビットなしで正しい出力を得られます。 –

+1

@MarcGravell私は別の理由であなたに同意します。文字列補間は、文字列を連結するときの最も遅い方法です。私は、優れたベンチマーク・ドットネット・ライブラリを使ってさまざまなコンカットのメソッドを実際にテストしました。これはstring.Join()の中で最も速いメソッドと比べてはるかに遅いメソッドでした。あなたがホットコードパスにいる場合は、そのことを覚えておいてください。ああ、興味深い; – Mantzas

0

C#6の構文にいくつかの問題がある場合、伝統的なstring.Format()を使用しないのはなぜですか?

double price = 5.05; 
Console.WriteLine(string.Format("{{Price = {0}}}", price.ToString("C"))); 
+1

;これは同じ問題を抱えていましたが、奇妙なことにConsole.WriteLine(string.Format( "{{Price = {0}}}"、price)); 'has * one * associativityと' Console.WriteLine string.Format( "{{Price = {0:C}}}"、price)); ** **動作は異なる**;実際にはコンパイラのバグかもしれません! –

3

興味回避策:何らかの理由で

var p = price.ToString("C"); 
Console.Write($"{{Price = {p}}}"); 

$"{{Price = {p}}}"$"{{Price = {p:C}}}"異なる関連性の結果を持って、コンパイラのバグのように感じています。私は尋ねます! string.Formatがどのように同じルールを適用するかと一致するので、であることに注意してください。故意に以前のフレームワークの奇妙さを伝播している可能性があります。

4

これは、string.Formatの動作に「奇妙」があり、生成された書式文字列に補間と挿入の間に正確な1対1のマッピングを持たせたいために発生します。つまり、言語の振る舞いは、string.Formatの動作を正確にモデル化します。

補間(中括弧内のもの)では、式はコロン(書式文字列を開始する)または中括弧で終了します。後者の場合、二重の中カッコは、文字列のリテラル部分の内部にないため、特別な意味を持ちません。そのため、3つの中括弧は補間に近いものとして解釈され、続いてリテラル(倍精度でエスケープされる)の中括弧が続きます。しかし、コロンの後には、その補間のために書式文字列が与えられ、その書式文字列は任意の文字列であり、中括弧で終わります。あなたの書式文字列の中に中括弧を入れたいのであれば、それを倍にするだけです。あなたが意図せずにやったことです。

CoolBotsは、まさにこの問題の説明のためのhttps://msdn.microsoft.com/en-us/library/txafckwd(v=vs.110).aspxの「エスケープ中括弧」セクションを読んで、このhttps://stackoverflow.com/a/42993667/241658

を処理する最善の方法を与えました。

+0

はい。それは「価格」がどこに行ったかを説明する...ありがとう! – schulmaster