在c# 6中声明使用字符串插值的长字符串

本文关键字:字符串 插值 声明 | 更新日期: 2023-09-27 18:10:32

我通常将长字符串连接起来:

Log.Debug("I am a long string. So long that I must " +
    "be on multiple lines to be feasible.");

这是非常有效的,因为编译器处理字符串字面值的连接。我也认为这是处理这个问题最干净的方法(这里权衡了选项)。

此方法在String.Format:

上运行良好。
Log.Debug(String.Format("Must resize {0} x {1} image " +
    "to {2} x {3} for reasons.", image.Width, image.Height,
    resizedImage.Width, resizedImage.Height));

然而,我现在希望在这些情况下不再使用String.Format,因为c# 6的字符串插值更具可读性。

我担心的是我不再有一个有效的,但干净的方式来格式化长字符串。

我的问题是如果编译器可以以某种方式优化像

这样的东西
Log.Debug($"Must resize {image.Width} x {image.Height} image " +
    $"to {resizedImage.Width} x {resizedImage.Height} for reasons.");

到上面的String.Format等价,或者如果有一个替代的方法,我可以使用,不会降低效率(由于不必要的连接),同时也保持我的代码整洁的结构(按照上面的链接提出的点)。

在c# 6中声明使用字符串插值的长字符串

程序:

var name = "Bobby Tables";
var age = 8;
String msg = $"I'm {name} and" +
    $" I'm {age} years old";

被编译,就好像你写了:

var name = "Bobby Tables";
var age = 8;
String msg = String.Concat(String.Format("I'm {0} and", name),
    String.Format(" I'm {0} years old", age));

您看到了摆脱Concat的困难—编译器已经重新编写了我们的插值文字,以使用String.Format期望的索引格式化器,但是每个字符串必须从0开始为其参数编号。天真地将它们连接起来会导致它们都插入name。为了正确解决这个问题,必须在$解析器的调用之间维护状态,以便将第二个字符串重新格式化为" I'm {1} years old"。或者,编译器可以尝试应用与字符串字面值连接相同的分析。我认为这将是一个合法的优化,即使字符串插值可能有副作用,但我不会感到惊讶,如果有一个角落的情况下,插补字符串连接改变程序的行为。这两种听起来都不可能,特别是考虑到逻辑已经存在,可以检测字符串字面量的类似条件,但是我可以理解为什么这个特性没有进入第一个版本。

我将以您认为最干净、最易读的方式编写代码,并且不担心微效率低下,除非它们被证明是一个问题。有句老话说,代码主要是供人类理解的。

也许它不像+那样可读,但无论如何,这是可能的。你只需要在{}之间换行:

Log.Debug($@"Must resize {image.Width} x {image.Height} image to {
    resizedImage.Width} x {resizedImage.Height} for reasons.");

SO的着色脚本不能很好地处理这种语法,但c#编译器可以;-)

在HTML中使用此字符串的特殊情况下(或使用任何解析器进行解析,其中多个空白无关紧要),我可以建议您使用@$""字符串(逐字插入字符串),例如:

$@"some veeeeeeeeeeery long string {foo} 
whatever {bar}"

c# 6.0中:

var planetName = "Bob";
var myName = "Ford"; 
var formattedStr = $"Hello planet {planetName}, my name is {myName}!";
// formattedStr should be "Hello planet Bob, my name is Ford!"

然后连接stringbuilder:

StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append(formattedStr);
// Then add the strings you need 

向stringbuilder添加更多字符串.....