C#中的多行字符串文字

时间:2009-07-08 20:03:35

标签: c# string shorthand

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

这就是我现在所拥有的:

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

我知道PHP有

<<<BLOCK

BLOCK;

C#有类似之处吗?

13 个答案:

答案 0 :(得分:1350)

您可以使用@前面的string符号形成verbatim string literal

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

当您使用此方法时,您还do not have to escape special characters,但Jon Skeet的答案中显示的双引号除外。

答案 1 :(得分:494)

它在C#中被称为verbatim string literal,这只是在文字之前放置@的问题。这不仅允许多行,而且还会关闭转义。例如,您可以这样做:

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

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

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

答案 2 :(得分:97)

另一个需要注意的是在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)

答案 3 :(得分:89)

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

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

呸。

所以我喜欢使用的解决方案是:保持一切与代码的其余部分完全一致:

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

当然,如果你只是想像你一样逻辑地分割SQL语句的行并且实际上不需要换行,你总是可以用Environment.NewLine代替" "

答案 4 :(得分:83)

作为旁注,使用C#6.0,您现在可以将插值字符串与逐字字符串文字组合:

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

答案 5 :(得分:36)

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

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

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

在C#中,陈述......

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

... 不会产生三行字符串,只能产生一个字符串;三个字符串的串联(每个字符串从不同的字面值初始化),其中没有一个字符串包含换行符。

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

建议使用逐字字符串,永远不要使StringBuilder s,String.Join s甚至嵌套函数与字符串反转,什么不是,让我觉得人们并不真正理解这个问题。或许我不明白。

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

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

答案 6 :(得分:11)

我还没有看到这个,所以我会在这里发布(如果你有兴趣传递一个字符串,你也可以这样做。)这个想法是你可以在多行上打破字符串并添加你想要的任何方式你自己的内容(也在多行)。这里&#34; tableName&#34;可以传递给字符串。

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

答案 7 :(得分:9)

添加多行:使用@

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";

答案 8 :(得分:4)

您可以使用 @ &#34;&#34;

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

答案 9 :(得分: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.

如果您愿意,可以运行以上here

答案 10 :(得分:1)

是的,您可以将字符串拆分为多行,而无需在实际的字符串中引入换行符,但这确实很漂亮:

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

技巧是引入评估结果为空的代码,并且该代码可以包含换行符而不影响输出。我将这种方法从this answer修改为一个类似的问题。

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

此单元测试显示了意图:

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

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

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

只有一个选项不依赖可能不会发生的编译器优化,这就是将您的定义放在一行上。如果您想依靠编译器优化,那么您已经拥有的+非常好;您不必使字符串左对齐,结果中也不会换行,并且只需进行一次操作,无需任何函数调用即可期待优化。

答案 11 :(得分:1)

我知道我参加聚会有点晚,但是我想向该主题的未来读者推荐https://www.buildmystring.com/。您可以使用此站点将任何代码转换为C#字符串文字。

答案 12 :(得分:-8)

您可以使用以下两种方法:

    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()中,您需要定义要使用的字符串和行长度,这非常简单。 谢谢。