C#6 中的长字符串插值线

Posted

技术标签:

【中文标题】C#6 中的长字符串插值线【英文标题】:Long string interpolation lines in C#6 【发布时间】:2015-10-24 05:43:08 【问题描述】:

我发现,虽然字符串插值在应用于我现有代码库的字符串格式调用时非常好,但考虑到通常首选的列限制,对于单行来说,字符串很快就会变得太长。特别是当被插值的表达式很复杂时。使用格式字符串,您有一个变量列表,您可以将其拆分为多行。

var str = string.Format("some text 0 more text 1",
    obj1.property,
    obj2.property);

有没有人有任何首选的方法来打破这些线?

我想你可以这样做:

var str = $"some text  obj1.property " +
  $" more text  obj2.property ;

【问题讨论】:

根据我的经验,最好避免插入复杂的表达式。而是在这种情况下提取一个变量。如果你这样做,并且你在字符串中有换行符的地方拆分,它通常会很好。 我对这个问题感到困惑。我只想要一个多行$"",它的工作方式类似于@"" Colonel Panic,问题是关于如何分解长插值线,这样我们就不会违反列宽要求,而不会在字符串文字本身中引入换行符。 $@"" 很棒,但是任何引入的换行符都将在字符串文字中。 要在 $@ 中支持 \t\r\n,请参阅问题 ***.com/questions/51991713/… 实际上,即使$"a: a" + $"b: b" 也会产生一个简单的字符串,从而阻止我在多行上破坏字符串插值。 ***.com/questions/52788306/… 也得到了答案。 【参考方案1】:

虽然 OP 要求其他内容,但我希望许多阅读此问题的人会喜欢多行插值 $"",其工作方式类似于 @""。为此,请使用$@""

$@"Height: height
Width: width
Background: background"

【讨论】:

他不想在输出中出现换行符,只希望代码本身换行 他明确表示,这个答案是为那些搜索如何使用字符串插值语法做多行字符串的观众准备的。【参考方案2】:

我以覆盖 ToString() 中的 StringBuilder 为例。

    // return employee data
    public override string ToString()
    
        StringBuilder buffer = new StringBuilder();
        buffer.AppendLine($"Number: EmployeeNumber");
        buffer.AppendLine($"Name: EmployeeName");
        buffer.AppendLine($"Address: PostalAddress");
        buffer.AppendLine($"Phone: PhoneNumber");
        buffer.AppendLine($"Age: EmployeeAge");
        buffer.AppendLine($"Gender: EmployeeGender");
        buffer.AppendLine($"Status: EmployeeStatus");
        buffer.AppendLine($"Manager: EmployeeManager");
        buffer.AppendLine($"Start: EmployeeStartDate.ToShortDateString()");
        return buffer.ToString();
    

【讨论】:

那为什么不 buffer.AppendFormat("0Number: 1", Environment.NewLine, EmployeeNumber); ??? 如果这样做很多,它不会表现良好。您正在对每行进行插值并将其添加到字符串构建器中。最好只进行多次追加调用并在下一项开始之前添加换行符。您当前的方式为需要垃圾收集的每个字符串和插值结果占用了内存。【参考方案3】:

就是这样:

var str = $"some text  obj1.property " +
          $" more text  obj2.property ";

注意$"..." + $"..." 中的第二个$

【讨论】:

请注意,这将对 String.Format 进行两次调用,并在内存中创建三个字符串(A 面、B 面和 A+B) 这不会阻止您对连接的字符串使用FormattableString 强制转换吗? 在当今的许多实现中,在具有 Gb 内存的 GHz CPU 上运行,额外的调用和额外的字符串不会给您带来性能问题。性能问题将由例如使用 O(n2) 的算法。我认为对这个人投反对票是不公平的。【参考方案4】:

可以将一行分成多行,但我不会说语法看起来更好了。

您需要使用$@ 语法来使用插入的verbatim 字符串,并且可以在... 参数内放置换行符,如下所示:

string s = $@"This is all 
    10
     going to be one long 
    DateTime.Now
     line.";

上面的字符串不会包含任何换行符,实际上会有这样的内容:

这是所有 10 条长线 01.08.2015 23.49.47 线。

(注,挪威格式)

现在,话虽如此,我不会停止使用string.Format。在我看来,其中一些字符串插值表达式看起来非常好,但更复杂的表达式开始变得非常难以阅读。考虑到除非你使用FormattableString,否则代码将被编译成对String.Format 的调用,我会说在有意义的地方继续使用String.Format

【讨论】:

可靠的答案。我很确定FormattableString 也可以归结为对String.Format 的调用。 这个答案帮助我弄清楚如何做与此完全相反的事情。感谢$@"" 语法! @AlexBooker 比这更复杂。你不能这样做FormattableString.Invarian($"Hello name" + \n "are you the owner of pet?");,因为它将两个内插字符串合并成一个简单的字符串。 在插入的逐字字符串中尊重换行符和制表符。在 C# 交互窗口中输入以下内容,生成的字符串将被格式化:。 > var name = "Simon"; var templateName = "How to interpolate a verbatim string"; var now = DateTime.UtcNow;. var output = $@"Hi name, This template is a demo of templateName. It was ran at now.ToString("o")"; > output。输出为"Hi Simon,\r\nThis template is a demo of How to interpolate a verbatim string.\r\n\r\nIt was ran at 2020-01-24T15:49:35.6678353Z" @Enzoaeneas 我认为您高估了 cmets 中的格式支持,但我理解并同意您的说法。【参考方案5】:

您可以将$@ 组合在一起以获得字符串插值和多行字符串文字:

var str = $@"some text  obj1.property 
     more text  obj2.property ";

但这会给你一个NewLine 字符,所以它可能不是你想要的。

【讨论】:

但是@实际上不是将换行符放入文字中吗? 确实如此。更新了我的答案以明确表示。 不仅是新行,还有新行的初始选项卡。为了在 Visual Studio 中使用 $@" 时正确描述实际的字符串格式,您必须从文本编辑器的最左侧开始每一行。 使用这个解决方案你不能使用例如字符串中的 \r 和 \n

以上是关于C#6 中的长字符串插值线的主要内容,如果未能解决你的问题,请参考以下文章

对 C# 6.0 中的字符串插值感到困惑 [重复]

[C#6] 4-string 插值

csharp C#中的插值字符串

csharp c#中的字符串插值

C# 10 新特性 —— 插值字符串优化

多行 C# 插值字符串文字