如何在字符串字面量中插入换行符?

181

在.NET中,我可以提供\r\n字符串字面值,但有一种方法可以插入类似于“换行符”特殊字符,如Environment.NewLine静态属性吗?


9
什么是问题? - iburlakov
12个回答

354

好的,简单的选项有:

  • string.Format

    string x = string.Format("first line{0}second line", Environment.NewLine);
    
  • 字符串拼接:

    string x = "first line" + Environment.NewLine + "second line";
    
  • C#6及以上版本支持字符串插值:

  • string x = $"first line{Environment.NewLine}second line";
    
    你可以在任何地方使用 \n,并替换为:
    string x = "first line\nsecond line\nthird line".Replace("\n",
                                                             Environment.NewLine);
    

    请注意,您无法将此作为字符串常量,因为Environment.NewLine的值只在执行时才可用。


1
当然,谢谢。但是我的意思是避免使用Environment.NewLine,我的问题是是否有“/newline”字面量。 - Captain Comic
3
@Captain:你为什么想避免使用 Environment.NewLine?相反,使用它是一个好习惯。 - abatishchev
21
在某些情况下,这是一种好的做法。但在其他情况下则不然。你真的需要知道你想要使用特定于平台的那一个。例如,如果你正在使用应该自己定义行终止符的网络协议,那么这不是一个好主意。 - Jon Skeet
1
@Captain Comic:我的最后一句话解释了为什么它不能是字面转义 - 你不能将它包含在字符串常量的元数据中,因为它不是一个常量值。 - Jon Skeet
1
也许我有些犹豫,因为使用加号运算符和使用格式化方法这两个选项都需要付出相当大的代价,而注入 '\newline' 字面量可能是最快的方法。但正如Jon所说,如果存在NewLine字面量,则必须是动态的和平台相关的。 - Captain Comic
此外,第三个选项可以与“using static” C#6 功能混合使用,以获得更整洁的字符串:using static System.Environment; ... $"first line{NewLine}second line"; - izce

37
如果您想要一个包含Environment.NewLine的常量字符串,则可以这样做:
const string stringWithNewLine =
@"first line
second line
third line";

编辑

由于这个字符串是常量,因此在编译时完成,因此这是编译器对换行符的解释。我似乎找不到解释此行为的参考文献,但我可以证明它按预期工作。我在Windows和Ubuntu(使用Mono)上编译了这段代码,然后进行了反汇编,得到了以下结果:

Windows 上的反汇编 Ubuntu 上的反汇编

如您所见,在Windows中,换行符被解释为 \r\n,而在Ubuntu中则为 \n。


1
编译器会自动在文本的每一行之间添加一个 Environment.NewLine。 因此,字符串被解释为:"第一行" + Environment.NewLine + "第二行" + Environment.NewLine + "第三行" - Tal Jerome
3
插入字符串字面量中换行的一个不太为人知的方法是在字符串中使用"\n"。你指定的行为有参考资料吗?这是真正的Environment.NewLine还是编译器对换行符的定义? - Grimace of Despair
1
你确定那不是代码编辑器插入的换行符吗?如果你将该代码复制粘贴到Windows上的编辑器中,它可能会被转换为\r\n。在类Unix平台上执行相同的操作,它可能会被转换为\n。 - Xiyng
小心这个问题。如果你在 CI/CD 服务器上(比如 Teamcity,使用服务器端检出)检出代码,它会将 CRLF 转换为 LF,并且字符串中不会有新行。 - Leszek P

16
var sb = new StringBuilder();
sb.Append(first);
sb.AppendLine(); // which is equal to Append(Environment.NewLine);
sb.Append(second);
return sb.ToString();

2
为什么要使用 first + Environment.NewLine + second 而不是更高效且(我认为)更易读的方法呢? - Jon Skeet
@Jon:更高效?我认为String.Format会一次性生成1个字符串(但由于特定文化的连接等原因,它在内部有点慢),而字符串连接则是1个结果+1个临时的,对吗? - abatishchev
1
@abatishchev:编译器将str+str+str转换为String.Concatenate,直接构建一个输出字符串(如果这些字符串是字面量,则在编译器中完成连接,如我所知)。 - Richard
@Richard:即多个但是单行字符串拼接(例如"a"+b+"c"+d等)在性能上是否与单个字符串相等?还是只是转换为String.Concatenate(a,b,c,d,etc),对吗? - abatishchev
@abatishchev:这就是为什么我在评论中没有建议使用string.Format。字符串连接不会产生任何临时字符串,因为编译器将调用string.Concat(first, Environment.NewLine, second) - Jon Skeet
显示剩余2条评论

3
string myText =
    @"<div class=""firstLine""></div>
      <div class=""secondLine""></div>
      <div class=""thirdLine""></div>";

那不是它:
string myText =
@"<div class=\"firstLine\"></div>
  <div class=\"secondLine\"></div>
  <div class=\"thirdLine\"></div>";

3

如果您真的想将换行符作为常量使用,可以这样做:

public readonly string myVar = Environment.NewLine;

在C#中,readonly关键字表示该变量只能被赋值一次。您可以在此处找到相关文档。它允许声明一个常量变量,其值直到执行时才知道。


3

一种更方便的在格式化字符串中添加Environment.NewLine的方法是创建一个字符串扩展方法,在普通的字符串格式化过程中,将文本中的{nl}替换为Environment.NewLine。

使用方法

   " X={0} {nl} Y={1}{nl} X+Y={2}".FormatIt(1, 2, 1+2);
   gives:
    X=1
    Y=2
    X+Y=3

代码

    ///<summary>
    /// Use "string".FormatIt(...) instead of string.Format("string, ...)
    /// Use {nl} in text to insert Environment.NewLine 
    ///</summary>
    ///<exception cref="ArgumentNullException">If format is null</exception>
    [StringFormatMethod("format")]
    public static string FormatIt(this string format, params object[] args)
    {
        if (format == null) throw new ArgumentNullException("format");

        return string.Format(format.Replace("{nl}", Environment.NewLine), args);
    }

注意

  1. 如果您想让ReSharper突出显示您的参数,请在方法上方添加以下属性:

    [StringFormatMethod("format")]

  2. 这种实现显然比仅使用String.Format要低效。

  3. 也许对于这个问题感兴趣的人也会对下一个问题感兴趣: C#中的命名字符串格式化


1
static class MyClass
{
   public const string NewLine="\n";
}

string x = "first line" + MyClass.NewLine + "second line"

3
系统已经定义了Environment.NewLine,请参考其他回答。 - Richard
@Richard: 根据我理解,OP想要使用内联字符串字面量,即 const string - abatishchev
@Richard Environment.NewLine 是静态的,而不是常量。 - user386349

1

较新版本的.NET允许您在文本前使用$,从而可以像以下方式一样在其中使用变量:

var x = $"Line 1{Environment.NewLine}Line 2{Environment.NewLine}Line 3";

1
一点上下文信息也不会有坏处。 - croxy
1
这并没有回答问题。一旦您拥有足够的声望,您将能够评论任何帖子;相反,提供不需要询问者澄清的答案。- 来自审核 - H. Pauwelyn
1
@H.Pauwelynツ:感谢反馈。我添加了一些上下文。在我看来,这个解决方案绝对回答了这个问题。 - DanielK

1
如果我理解正确的话:将"\r\n"连接起来,就可以在textbox中得到下面的新行。我的示例运行正常 -
   string s1 = comboBox1.Text;     // s1 is the variable assigned to box 1, etc.
   string s2 = comboBox2.Text;

   string both = s1 + "\r\n" + s2;
   textBox1.Text = both;

一般的回答可能是在文本框中使用定义的类型样式s1s2

1
如果您正在处理Web应用程序,您可以尝试这个。
StringBuilder sb = new StringBuilder();
sb.AppendLine("Some text with line one");
sb.AppendLine("Some mpre text with line two");
MyLabel.Text = sb.ToString().Replace(Environment.NewLine, "<br />")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接