web-dev-qa-db-ja.com

C#の複数行文字列リテラル

C#で複数行の文字列リテラルを作成する簡単な方法はありますか?

これが私が今持っているものです:

string query = "SELECT foo, bar"
+ " FROM table"
+ " WHERE id = 42";

PHPが知っている

<<<BLOCK

BLOCK;

C#にも似たようなものがありますか?

864
Chet

stringの前に@記号を使用して、 逐語的文字列リテラル を形成できます。

string query = @"SELECT foo, bar
FROM table
WHERE id = 42";

Jon Skeetの答えで示されているように二重引用符を除いて、この方法を使用するときは 特殊文字 をエスケープする必要はありません。

1338
John Rasch

C#では 逐語的文字列リテラル と呼ばれていますが、リテラルの前に@を付けるだけです。これは複数行を許可するだけでなく、エスケープを無効にします。だから例えばあなたが行うことができます:

string query = @"SELECT foo, bar
FROM table
WHERE name = 'a\b'";

二重引用符が必要な場合は、余分な二重引用符を追加する必要があります。

string quote = @"Jon said, ""This will work,"" - and it did!";
491
Jon Skeet

もう1つ注意が必要なのは、string.Formatでの文字列リテラルの使用です。その場合は中括弧/大括弧 '{'と '}'をエスケープする必要があります。

// this would give a format exception
string.Format(@"<script> function test(x) 
      { return x * {0} } </script>", aMagicValue)
// this contrived example would work
string.Format(@"<script> function test(x) 
      {{ return x * {0} }} </script>", aMagicValue)
96
Martin Clarke

私が見つけた文字列リテラルを使うことの問題はそれがあなたのコードが少し " 変な "に見えるようにすることができるということです。

    var someString = @"The
quick
brown
fox...";

やあ.

それで私が使うのが好きな解決策は、すべてをあなたのコードの残りとうまく調和させ続ける:

var someString = String.Join(
    Environment.NewLine,
    "The",
    "quick",
    "brown",
    "fox...");

もちろん、SQLステートメントの行を論理的に分割したいだけで、実際には新しい行を必要としない場合は、Environment.NewLine" "に置き換えることができます。

87
dav_i

ちなみに、C#6.0では、補間された文字列と逐語的な文字列リテラルを組み合わせることができます。

string camlCondition = $@"
<Where>
    <Contains>
        <FieldRef Name='Resource'/>
        <Value Type='Text'>{(string)parameter}</Value>
    </Contains>
</Where>";
83
Heliac

文字列と文字列リテラルを混同し続けるのはなぜですか?受け入れられた答えは、別の質問に対する素晴らしい答えです。これではありません。

これは古い話題ですが、私はOPと同じ質問をしてここに来ました、そしてそれが人々がそれを誤解し続けているのを見るのはいらいらします。それとも誤解しているかもしれませんが、わかりません。

大まかに言って、文字列はプログラムの実行中にテキスト文字にマッピングできる一連のバイトを含むコンピュータメモリの領域です。一方、文字列リテラルは、コンパイルされていないソースコードの一部であり、文字列が表示されるプログラムの実行中に文字列を後で初期化するために使用される値を表します。

C#では、ステートメント...

 string query = "SELECT foo, bar"
 + " FROM table"
 + " WHERE id = 42";

... しない 3行の文字列を作成しますが、1行のライナーを作成します。改行修飾子を含まない3つの文字列(それぞれ異なるリテラルから初期化される)の連結。

OPが尋ねているように思えるのは、少なくともコンパイルされた文字列の中で、ソースコードに見られるような改行を導入する方法ではなく、明確にするための分割方法です。 、ソースコード内の1行のテキスト なし コンパイルされた文字列に改行を挿入します。そして、長い実行時間を必要とせずに、ソースコードから来る複数の部分文字列を結合するのに費やしました。 JavaScriptまたはC++の複数行の文字列リテラル内の末尾の円記号のようなものです。

逐語的な文字列の使用を提案し、StringBuilders、String.Joins、さらには文字列の反転を伴うネストされた関数さえも決して思い出させないでください。それとも理解できないかもしれません。

私が知っている限りでは、C#には(少なくとも10年前から使用している旧石器時代のバージョンでは)実行ではなくコンパイル中に解決できる複数行の文字列literalsをきれいに生成する機能がありません。 。

現在のバージョンではサポートされているかもしれませんが、文字列と文字列リテラルの違いを共有したいと思いました。

36
Carvo Loco

私はこれを見たことがないので、ここに投稿します(あなたが文字列を渡すことに興味があるならこれをやることもできます)。複数の行に)任意の方法であなたが望む。ここで "tableName"を文字列に渡すことができます。

    private string createTableQuery = "";

    void createTable(string tableName)
    {

         createTableQuery = @"CREATE TABLE IF NOT EXISTS
                ["+ tableName  + @"] (
               [ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
               [Key] NVARCHAR(2048)  NULL, 
               [Value] VARCHAR(2048)  NULL
                                )";
    }
11
RobertHana

@ および "" を使用できます。

        string sourse = @"{
        ""items"":[
        {
            ""itemId"":0,
            ""name"":""item0""
        },
        {
            ""itemId"":1,
            ""name"":""item1""
        }
        ]
    }";
4
vovkas

はい、実際の文字列に改行を入れることなく、文字列を複数の行に分割することができますが、それはあまり意味がありません。

string s = $@"This string{
string.Empty} contains no newlines{
string.Empty} even though it is spread onto{
string.Empty} multiple lines.";

トリックは空と評価されるコードを導入することです、そしてそのコードは出力に影響を与えずに改行を含むかもしれません。私はこのアプローチを この答え から同様の質問に適応させました。

何が問題なのか混乱しているようですが、ここで欲しいのは改行文字を含まない文字列リテラルで、その定義が複数行にわたることであるというヒントが2つあります。 (コメントの中で彼はそう言っています、そして「ここに私が持っているものは」その中に改行を含む文字列を作成しないコードを示しています)

このユニットテストはその意図を示しています。

    [TestMethod]
    public void StringLiteralDoesNotContainSpaces()
    {
        string query = "hi"
                     + "there";
        Assert.AreEqual("hithere", query);
    }

上記のqueryの定義を1つの文字列リテラルになるように変更してください。2つの文字列リテラルを連結してコンパイラで最適化してもしなくてもかまいません。

C++のアプローチでは、各行をバックスラッシュで終了し、改行文字をエスケープして出力に表示しないようにします。残念ながら、結果に余分な空白を追加しないためには、最初の行以降の各行を揃えたままにしなければならないという問題が依然としてあります。

起こらないかもしれないコンパイラ最適化に依存しない唯一の選択肢があります。それはあなたの定義を一行にすることです。もしあなたがコンパイラの最適化に頼りたいのなら、あなたがすでに持っている+は素晴らしいです。文字列を左揃えにする必要はなく、結果に改行を入れる必要もありません。最適化を期待するのは、1回の操作で、関数呼び出しは不要です。

1
TamaMcGlinn

スペースや改行が不要な場合は、文字列の追加でうまくいくようです。

var myString = String.Format(
  "hello " + 
  "world" +
  " i am {0}" +
  " and I like {1}.",
  animalType,
  animalPreferenceType
);
// hello world i am a pony and I like other ponies.

上記の ここ を実行することができます。

1
rattray