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


1046

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

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

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

PHPには

<<<BLOCK

BLOCK;

C#にも同様のものはありますか?


1
この例では改行はありません。欲しいですか?
ウェイク2009

8
いいえ。私は、可視性/コードの清潔さのために、複数の行を必要としていました。
チェット

6
その場合、逐語的文字列には改行が含まれます。必要に応じて、@ "..."。Replace(Environment.NewLine、 "")を使用できます。
weiqure 2009

9
42特にユーザー入力からのものである場合は、SQLインジェクションを回避するために、パラメータとしてバインドすることを検討する必要があります。
JensMühlenhoff2013年

@JensMühlenhoffコードで定義されているハードコードされた文字列をどのように注入するのですか?
ボーイ氏

回答:


1590

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

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

また、この方法を使用する場合は、Jon Skeetの回答に示されている二重引用符を除いて、特殊文字をエスケープする必要はありません


43
それはとにかく文字列リテラルです- @記号が付いた逐語的な文字列リテラルです。
Jon Skeet、

95
文字列に二重引用符( ")が含まれている場合は、次のようにエスケープできます:" "(2つの二重引用符文字)
Muad'Dib

8
新しい行を作成せずに上記を行う方法はありますか?プラス( "hi" + "there")を使用せずに、IDEで折り返して表示したい非常に長いテキストがあります。
noelicus

2
@noelicus -ではない、本当に、しかし、あなたは上記のweiqureの技術を用いてこれを回避することができます:@"my string".Replace(Environment.NewLine, "")
ジョン・ラッシュ

8
@afsharm $ @ "text"を使用できます
Patrick McDonald

566

これはC#では逐語的文字列リテラルと呼ばれ、@をリテラルの前に置くだけの問題です。これは複数行を許可するだけでなく、エスケープをオフにします。たとえば、次のようにできます。

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

ただし、これには文字列への改行(ソースの改行を使用)が含まれます。SQLの場合、これは無害であるだけでなく、おそらく文字列が表示されるすべての場所で読みやすさが向上しますが、他の場所では必要ない場合もあります。または、結果の文字列からそれらを削除します。

エスケープの唯一のビットは、二重引用符が必要な場合、余分な二重引用符記号を追加する必要があることです。

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

2
この答えは正しくありません。OPが望まない改行を導入します。
TamaMcGlinn

@TamaMcGlinn:私はその答えに何かを追加します-OPが質問を書いたときは明確ではありませんでした。
Jon Skeet、

105

私が見つけた文字列リテラルを使用する際の問題は、文字列自体にスペースが入らないようにするために、完全に左揃えにする必要があるため、コードが「奇妙」に見える可能性があることです。

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

ああ。

したがって、私が使用したいソリューションは、すべてをコードの残りの部分とうまく調和させます。

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

もちろん、SQLステートメントの行を論理的に論理的に分割したいだけで、実際には新しい行が必要ない場合は、いつでもの代わりにEnvironment.NewLine使用できます" "


2
とてもきれいになりました、ありがとう。また、String.Concatも同様に機能し、区切り記号は必要ありません。
Seth

ありがとう。SQLの区切り文字 ""を使用したString.Joinは、インデント/括弧の照合が可能で、先行スペースを追加する必要がないため、気に入っています。
RobはTVSeries.comで2015

7
醜いですが、最初のバージョンを実行するためのコードは必要ありません。2番目のオプションには、明らかに、個別の文字列を連結するためのランタイムオーバーヘッドがあります。
コーディングが

@GoneCoding、それでよろしいですか?コンパイラーは、連結を最適化する場合があります。
ウィリアムジョクシュ

@WilliamJockusch:一般に、演算子以外の関数呼び出し(結合など)はそのまま残され、最適化されません。コンパイルされたコードをチェックすることをお勧めしますが、呼び出しが最適化されていないことを知っています。
コーディング終了

104

注意すべきもう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)

14
そして、それはどのような違いをもたらしますか?「@」の有無にかかわらず、「{」を印刷可能な文字として取得するには「{{」を2倍にする必要があります。これは、文字列の内容ではなく、String.Formatの問題です。
greenoldman 2011

12
これは、Javascriptコードを文字列に挿入したい人にとっては注目すべき問題です。これは、通常の文字列よりも逐語的な文字列リテラルでより頻繁に実行される可能性があります。
Ed Brannin 2013年

2
新しいC#6.0では、インデックス付きプロパティ演算子を逐語的文字列リテラルと一緒に使用できます(この$ @ "Value is {this.Value}";など)
Heliac

2
@Heliac補間された文字列もその構文でリテラルになる可能性があることを意味すると思います。var query = $ @ "select foo、bar from table where id = {id}";
brianary

102

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

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

10
かっこいい、今まで知りませんでした。誰かが興味を持っている場合:$の事は「補間された文字列」と呼ばれ、ここで詳細を読むことができます:msdn.microsoft.com/en-us/library/dn961160.aspx
Hauke P.

tx、文言を修正
ヘリアック'20

1
私は文字通り中かっこを2倍にする必要がある$@"{{example literal text { fooString }. }}" と思います。たとえば、Angular、React、Vue.jsは逆の規則を使用しているため、これはいくつかを混乱させる可能性があります。
Patrick Szalapski、2018年

58

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

これは古いトピックであることはわかっていますが、おそらくOPと同じ質問でここに来ました。人々がそれを誤って読み続けるのを見るのはイライラします。それとも私はそれを誤解しているかもしれません、私は知りません。

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

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

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

... しない 3行の文字列が、1つのライナーを生産。3つの文字列の連結(それぞれが別のリテラルから初期化されます)には、改行修飾子は含まれません。

OPが要求しているように見える-少なくとも私がそれらの単語について要求しているのは-コンパイルされた文字列に、ソースコードで見られるものを模倣する改行を導入する方法ではなく、明確にするために長く分割する方法です、コンパイルされた文字列に改行導入することなく、ソースコード内の1行のテキスト。そして、長い実行時間を必要とせずに、ソースコードからの複数の部分文字列の結合に費やしました。JavaScriptまたはC ++の複数行文字列リテラル内のバックスラッシュのように。

逐語的文字列の使用、StringBuilders、String.Joins、または文字列の逆転を伴うネストされた関数などの使用を提案すると、人々は質問を本当に理解していないと思います。それとも私はそれを理解していません。

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

たぶん現在のバージョンはそれをサポートしていますが、私は文字列と文字列リテラルの間で私が感じる違いを共有したいと思いました。

更新:

(MeowCat2012のコメントより)できます。OPによる「+」アプローチが最適です。仕様によると、最適化は保証されています:http : //stackoverflow.com/a/288802/9399618


1
いくつかの(私を含む)が元の質問を見ていたかもしれない混乱は、ヒアドキュメント形式(シェル、php、perlなど)に改行が含まれていることです。したがって、OPがPHPのヒアドキュメントと比較されている場合、改行を含めることは問題ではありませんでした。
Tanktalus 2018年

丁度。私の知る限り、「いいえ、C#ではこれを行うことはできません」という答えは正しいです。
TamaMcGlinn

Javaでは、このような連結された文字列は、コンパイルされたバイトコードで単一の文字列リテラルになると言われました。たぶんドットネットもそうですか?
ニャー猫2012年

2
あなたはできる。OPによる「+」アプローチが最適です。仕様によると、最適化は保証されています:stackoverflow.com/a/288802/9399618それでも、あなたは問題を理解している数少ない人の1人です。誤解を招く可能性があるが受け入れられた回答を削除または折りたたむことは可能ですか?
ニャー猫2012年

1
ヒントをありがとう、@ MeowCat2012。いくつかの逆コンパイルされたコードを見ると、確かにそうです。
Carvo Loco

12

私はこれを見たことがないので、ここに投稿します(文字列を渡すことに興味がある場合は、これも行うことができます)。文字列を複数行に分割して、独自のコンテンツを追加することもできます(また複数行で)好きなように。ここで「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
                                )";
    }

10
かなり危険だと思います。誰かがsqlインジェクションをそのように作成するのは簡単です。
カイ

4
クエリ文字列内のすべての変数(存在する場合)がコード定数または別の安全なソースからのものであることがわかっていれば問題ありません。たとえば、createTable("MyTable"); OPの質問は、コードに複数行の文字列リテラルを直接入力する方法に関するものでした。 、データベースクエリ自体の構築方法ではありません。:)
dbeachy1 2015

2
特にプラス(+)の数が多い場合は、おそらく文字列ビルダーを使用する必要があります。
gldraphael、2015

8

@""を使用できます。

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

2
@は逐語的な文字列を表し、 ""は二重引用符をエスケープするためのものです。
AFract

4

はい、実際の文字列に改行を導入しなくても、文字列を複数の行に分割できますが、かなり問題です。

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);
    }

上記のクエリの定義を変更して、コンパイラによって1つに最適化される場合とされない場合がある2つの文字列リテラルを連結するのではなく、1つの文字列リテラルになるようにします。

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

起こり得ないコンパイラの最適化に依存しないオプションが1つだけあります。それは、定義を1行に置くことです。+コンパイラーの最適化に依存したい場合、すでに持っている+は素晴らしいです。文字列を左揃えにする必要はありません。結果に改行が表示されることはありません。最適化を期待できるのは、関数呼び出しではなく、1つの操作だけです。


1
クリエイティブ。ただし、(確認されていません)これはフォーマット文字列として扱われ、最適化される場合とされない場合があります。一方、OPによる「+」アプローチが最適です。仕様によると、最適化は保証されています:stackoverflow.com/a/288802/9399618
Meow Cat 2012

4

複数行を追加:@を使用

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

真ん中に文字列値を追加:$を使用

string text ="beer";
string query = $"SELECT foo {text} bar ";

複数行の文字列を中央に値を追加:$ @を使用

string text ="Customer";
string query = $@"SELECT foo, bar
FROM {text}Table
WHERE id = 42";

3

スペース/改行が必要ない場合は、文字列の追加が機能するようです:

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.

必要に応じて、ここで上記を実行できます。


2
このアプローチの1つの(偶然に実証された)欠点は、必要な場所にスペースを含めるように非常に注意する必要があることです。私は私が取ったよりも一貫したアプローチをお勧めします(たとえば、常に行の先頭に)。
ラトレイ

ただし、string + stringはOPの最初の部分です。
TamaMcGlinn 2018

1

私はパーティーに少し遅れていることを知っていますが、このスレッドの将来の読者にhttps://www.buildmystring.com/をお勧めしたいと思います。このサイトを使用して、任意のコードをC#文字列リテラルに変換できます。


-10

この2つの方法を使用できます。

    private static String ReverseString(String str)
    {
        int word_length = 0;
        String result = "";
        for (int i = 0; i < str.Length; i++)
        {
            if (str[i] == ' ')
            {
                result = " " + result;
                word_length = 0;
            }
            else
            {
                result = result.Insert(word_length, str[i].ToString());
                word_length++;
            }
        }
        return result;
    }
//NASSIM LOUCHANI
    public static string SplitLineToMultiline(string input, int rowLength)
    {
        StringBuilder result = new StringBuilder();
        StringBuilder line = new StringBuilder();

        Stack<string> stack = new Stack<string>(ReverseString(input).Split(' '));

        while (stack.Count > 0)
        {
            var word = stack.Pop();
            if (word.Length > rowLength)
            {
                string head = word.Substring(0, rowLength);
                string tail = word.Substring(rowLength);

                word = head;
                stack.Push(tail);
            }

            if (line.Length + word.Length > rowLength)
            {
                result.AppendLine(line.ToString());
                line.Clear();
            }

            line.Append(word + " ");
        }

        result.Append(line);
        return result.ToString();
    }

SplitLineToMultiline()では、使用する文字列と行の長さを定義する必要があります。これは非常に簡単です。ありがとうございました 。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.