1265

有没有一种简单的方法可以在 C# 中创建多行字符串文字?

这是我现在拥有的:

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

我知道 PHP 有

<<<BLOCK

BLOCK;

C#有类似的东西吗?

4

11 回答 11

1907

您可以使用@a 前面的符号string来形成逐字字符串文字

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

使用此方法时,您也不必转义特殊字符,Jon Skeet 的答案中显示的双引号除外。

于 2009-07-08T20:04:47.937 回答
641

它在 C# 中称为逐字字符串文字,只需将 @ 放在文字之前即可。这不仅允许多行,而且还关闭转义。因此,例如,您可以这样做:

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

但是,这包括在字符串中的换行符(使用您的源代码中的任何换行符)。对于 SQL,这不仅是无害的,而且可能会提高您在任何地方看到字符串的可读性 - 但在其他地方可能不需要它,在这种情况下,您要么不需要使用多行逐字字符串文字开始,或从结果字符串中删除它们。

唯一的转义是如果你想要一个双引号,你必须添加一个额外的双引号符号:

string quote = @"Jon said, ""This will work,"" - and it did!";
于 2009-07-08T20:06:27.917 回答
174

附带说明一下,在 C# 6.0 中,您现在可以将内插字符串与逐字字符串文字结合起来:

string camlCondition = $@"
<Where>
    <Contains>
        <FieldRef Name='Resource'/>
        <Value Type='Text'>{(string)parameter}</Value>
    </Contains>
</Where>";
于 2015-08-13T06:58:58.503 回答
130

我发现使用字符串文字的问题是它会使您的代码看起来有点“奇怪”,因为为了不在字符串本身中出现空格,它必须完全左对齐:

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

呸。

所以我喜欢使用的解决方案是:

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

当然,如果您只是想像现在这样在逻辑上拆分 SQL 语句的行并且实际上不需要新行,您总是可以替换Environment.NewLine" ".

于 2014-08-07T08:20:36.210 回答
105

另一个需要注意的问题是在 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)
于 2009-09-24T09:28:46.830 回答
75

为什么人们总是将字符串与字符串文字混淆?接受的答案是对不同问题的一个很好的答案;不是这个。

我知道这是一个老话题,但我来到这里可能与 OP 相同的问题,看到人们如何继续误读它令人沮丧。或者我看错了,我不知道。

粗略地说,字符串是计算机内存的一个区域,在程序执行期间,它包含可以映射到文本字符的字节序列。另一方面,字符串字面量是一段尚未编译的源代码,它表示稍后在其出现的程序执行期间用于初始化字符串的值。

在 C# 中,语句...

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

...产生三行字符串,而是产生单行;三个字符串的串联(每个都从不同的文字初始化),其中没有一个包含换行符。

OP 似乎在问什么——至少我会用这些话问什么——不是如何在编译的字符串中引入模仿源代码中的换行符,而是如何长时间分解以保持清晰, 源代码中的单行文本,而不会在编译的字符串中引入中断。并且不需要延长执行时间,就可以将来自源代码的多个子字符串连接起来。就像 javascript 或 C++ 中多行字符串文字中的尾部反斜杠一样。

建议使用逐字字符串、nevermind StringBuilders、String.Joins 甚至是带有字符串反转的嵌套函数等等,这让我觉得人们并没有真正理解这个问题。或者也许我不明白。

据我所知,C# 没有(至少在我仍在使用的旧石器时代版本中,从前十年开始)具有干净地生成多行字符串文字的功能,这些文字可以在编译期间而不是执行期间解决。

也许当前版本确实支持它,但我想我会分享我在字符串和字符串文字之间感知的差异。

更新:

(来自 MeowCat2012 的评论)你可以。OP 的“+”方法是最好的。根据规范保证优化:http ://stackoverflow.com/a/288802/9399618

于 2016-07-17T17:08:57.707 回答
44

添加多行:使用@

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";
于 2020-01-17T08:41:32.387 回答
20

您可以使用@""

        string sourse = @"{
        ""items"":[
        {
            ""itemId"":0,
            ""name"":""item0""
        },
        {
            ""itemId"":1,
            ""name"":""item1""
        }
        ]
    }";
于 2018-06-06T08:51:33.287 回答
14

我还没有看到这个,所以我会把它贴在这里(如果你有兴趣传递一个字符串,你也可以这样做。)这个想法是你可以将字符串分成多行并添加你自己的内容(也在多行上)以您希望的任何方式。这里“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
                                )";
    }
于 2014-09-19T03:40:37.467 回答
7

是的,您可以将一个字符串拆分为多行,而无需在实际字符串中引入换行符,但它并不漂亮:

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

诀窍是引入评估为空的代码,并且该代码可能包含换行符而不影响输出。我将这种方法从这个答案改编为类似的问题。

对于问题是什么,显然有些混淆,但有两个提示,我们在这里想要的是一个不包含任何换行符的字符串文字,其定义跨越多行。(在他这么说的评论中,“这就是我所拥有的”显示了不会创建带有换行符的字符串的代码)

此单元测试显示了意图:

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

更改上述查询的定义,使其成为一个字符串文字,而不是两个字符串文字的串联,编译器可能会或可能不会优化为一个字符串文字。

C++ 方法是用反斜杠结束每一行,导致换行符被转义并且不会出现在输出中。不幸的是,仍然存在这样的问题,即第一行之后的每一行都必须左对齐,以免在结果中添加额外的空格。

只有一个选项不依赖于可能不会发生的编译器优化,那就是将您的定义放在一行上。如果你想依赖编译器优化,你已经拥有的 + 很棒;你不必左对齐字符串,你不会在结果中得到换行符,而且它只是一个操作,没有函数调用,可以期待优化。

于 2018-12-21T16:12:29.413 回答
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.

如果您愿意,可以在此处运行上述代码。

于 2015-05-13T08:11:59.627 回答