C#で複数行の文字列リテラルを作成する簡単な方法はありますか?
これが私が今持っているものです:
string query = "SELECT foo, bar"
+ " FROM table"
+ " WHERE id = 42";
私はPHPが持っていることを知っています
<<<BLOCK
BLOCK;
C#には似たようなものがありますか?
@
の前にある記号を使用して、逐語的な文字列リテラルstring
を形成できます。
string query = @"SELECT foo, bar
FROM table
WHERE id = 42";
また、Jon Skeetの回答に示されている二重引用符を除いて、このメソッドを使用するときに特殊文字をエスケープする必要はありません。
これは、C#では逐語的な文字列リテラルと呼ばれ、リテラルの前に@を付けるだけです。これにより、複数の行が許可されるだけでなく、エスケープもオフになります。たとえば、次のことができます。
string query = @"SELECT foo, bar
FROM table
WHERE name = 'a\b'";
ただし、これには、文字列への改行(ソースにある改行を使用)が含まれます。SQLの場合、これは無害であるだけでなく、文字列が表示される場所での読みやすさを向上させる可能性がありますが、他の場所では必要ない場合があります。その場合、最初に複数行の逐語的な文字列リテラルを使用する必要はありません。または、結果の文字列からそれらを削除します。
エスケープの唯一のビットは、二重引用符が必要な場合は、余分な二重引用符記号を追加する必要があるということです。
string quote = @"Jon said, ""This will work,"" - and it did!";
補足として、C#6.0では、補間された文字列を逐語的な文字列リテラルと組み合わせることができるようになりました。
string camlCondition = $@"
<Where>
<Contains>
<FieldRef Name='Resource'/>
<Value Type='Text'>{(string)parameter}</Value>
</Contains>
</Where>";
私が見つけた文字列リテラルの使用に関する問題は、文字列自体にスペースを入れないために、コードを完全に左揃えにする必要があるため、コードが少し「奇妙」に見える可能性があることです。
var someString = @"The
quick
brown
fox...";
うん。
したがって、私が使用したいソリューションは、すべてをコードの残りの部分とうまく整合させます。
var someString = String.Join(
Environment.NewLine,
"The",
"quick",
"brown",
"fox...");
そしてもちろん、SQLステートメントの行を自分のように論理的に分割したいだけで、実際には新しい行を必要としない場合は、いつでも。の代わりEnvironment.NewLine
に使用できます" "
。
注意すべきもう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)
なぜ人々は文字列と文字列リテラルを混同し続けるのですか?受け入れられた答えは、別の質問に対する素晴らしい答えです。これではありません。
これは古いトピックだと思いますが、OPと同じ質問でここに来たので、人々がそれを読み間違え続けるのを見るのはイライラします。または多分私はそれを誤解しています、私は知りません。
大まかに言えば、文字列は、プログラムの実行中に、テキスト文字にマップできる一連のバイトを含むコンピュータメモリの領域です。一方、文字列リテラルは、まだコンパイルされていないソースコードの一部であり、後で文字列が表示されるプログラムの実行中に文字列を初期化するために使用される値を表します。
C#では、ステートメント...
string query = "SELECT foo, bar"
+ " FROM table"
+ " WHERE id = 42";
... 3行の文字列ではなく、1つのライナーを生成します。3つの文字列(それぞれが異なるリテラルから初期化されたもの)の連結。いずれにも改行修飾子は含まれていません。
OPが求めているように見えること(少なくとも私がそれらの単語で求めていること)は、コンパイルされた文字列に、ソースコードで見つかったものを模倣する改行を導入する方法ではなく、明確にするために長い間分割する方法です、コンパイルされた文字列に区切りを導入せずに、ソースコードに1行のテキスト。また、実行時間を延長することなく、ソースコードからの複数のサブストリングの結合に費やしました。javascriptまたはC++の複数行の文字列リテラル内の末尾のバックスラッシュのように。
逐語的な文字列の使用を提案し、StringBuilder
s、String.Join
s、または文字列の反転を伴う入れ子関数などを気にしないでください。人々はその質問を本当に理解していないと思います。または多分私はそれを理解していません。
私の知る限り、C#には(少なくとも過去10年間、私がまだ使用している旧石器時代のバージョンでは)実行ではなくコンパイル中に解決できる複数行の文字列リテラルをきれいに生成する機能がありません。
現在のバージョンはそれをサポートしているかもしれませんが、文字列と文字列リテラルの違いを共有したいと思いました。
アップデート:
(MeowCat2012のコメントから)できます。OPによる「+」アプローチが最適です。仕様によると、最適化が保証されています:http ://stackoverflow.com/a/288802/9399618
複数行を追加:@を使用
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";
@と""を使用できます。
string sourse = @"{
""items"":[
{
""itemId"":0,
""name"":""item0""
},
{
""itemId"":1,
""name"":""item1""
}
]
}";
私はこれを見たことがないので、ここに投稿します(文字列を渡すことに興味がある場合は、これも行うことができます)。アイデアは、文字列を複数行に分割して、独自のコンテンツを追加できるということです(複数の行で)任意の方法で。ここで、「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
)";
}
はい、実際の文字列に改行を導入せずに文字列を複数の行に分割できますが、それはきれいではありません。
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回の操作であり、関数呼び出しはありません。
スペース/改行が必要ない場合は、文字列の追加が機能するようです。
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.
必要に応じて、ここで上記を実行できます。