所以,我刚刚在评论部分与用户进行了以下对话.
我:
Year year = new Year{ State = States.Happy };
他们:
eventStream.ReceiveJoke += joke => Console.WriteLine($"Pretty nice joke: {joke}, Thanks!!!");
而且,像我一样,我不知道他的美元符号是什么意思,但我觉得问他是太尴尬了.
它是一个插值字符串文字,在C#6中引入.
它大致相当于:
eventStream.ReceiveJoke += joke => Console.WriteLine(string.Format("Pretty nice joke: {0}, Thanks!!!", joke));
编译器在引入的任何字符串文字中查找大括号$
,并对其应用字符串格式.你可以使用(大多数)任意表达式,而不仅仅是变量,例如
Console.WriteLine($"{year.State} {2000 + 16}"); // Happy 2016
它是允许您创建插值字符串的符号,它是C#6的新功能,我喜欢它.
它也是一个Syntax Sugar,我将在最后解释它的含义.
public string Receive(int value) { return String.Format("Received: {0}", value); } public string Receive6(int value) { return $"Received: {value}"; }
它们将具有相同的IL实现,在此处查看来自Receive的IL(在调试模式下,未优化)
.method public hidebysig instance string Receive (int32 'value') cil managed { // Method begins at RVA 0x22d4 // Code size 22 (0x16) .maxstack 2 .locals init ( [0] string ) IL_0000: nop IL_0001: ldstr "Received: {0}" IL_0006: ldarg.1 IL_0007: box [mscorlib]System.Int32 IL_000c: call string [mscorlib]System.String::Format(string, object) IL_0011: stloc.0 IL_0012: br.s IL_0014 IL_0014: ldloc.0 IL_0015: ret } // end of method Program::Receive
.method public hidebysig instance string Receive6 (int32 'value') cil managed { // Method begins at RVA 0x22f8 // Code size 22 (0x16) .maxstack 2 .locals init ( [0] string ) IL_0000: nop IL_0001: ldstr "Received: {0}" IL_0006: ldarg.1 IL_0007: box [mscorlib]System.Int32 IL_000c: call string [mscorlib]System.String::Format(string, object) IL_0011: stloc.0 IL_0012: br.s IL_0014 IL_0014: ldloc.0 IL_0015: ret } // end of method Program::Receive6
正如你自己可以看到的那样,IL几乎是一样的.
在计算机科学中,语法糖是编程语言中的语法,旨在使事物更易于阅读或表达.它使语言"更甜"供人类使用:事物可以更清晰,更简洁地表达,或者以某些人可能更喜欢的替代方式表达.
来自https://en.wikipedia.org/wiki/Syntactic_sugar
因此,编写大量的string.Format
,使用字符串插值,编译器将为您工作并转换您编写的语法,在另一个代码中,在这种情况下,使用string.Format
.
是的,你可以,看下面
public static string Receive(int value) => string.Format("Received: {0, 15:C}", value); public static string Receive6(int value) => $"Received: {value,15:C}"; Console.WriteLine(Receive(1)); Console.WriteLine(Receive6(1)); Console.WriteLine($"Current data: {DateTime.Now: MM/dd/yyyy}")
输出(我的文化是pt-br)
Received: R$ 1,00 Received: R$ 1,00 Current data: 01/01/2016
Obs.:我想提一下,没有性能差异,因为使用字符串插值e string.Format是完全一样的
简而言之,它是提高代码可读性并减少代码长度的好方法.它比String.Concat
或者+运算符要好得多,因为字符串插值只执行一次String.Format
(并且它实际上是编译为String.Format
方法调用),你可以从左到右读取表达式.
String.Format
它的堂兄弟是非常多才多艺和有用的,但它们的使用有点笨重且容易出错.特别不幸的是{0}
在格式字符串中使用了等号占位符,它必须与单独提供的参数对齐:var s = String.Format("{0} is {1} year{{s}} old", p.Name, p.Age);字符串插值允许您通过在字符串文字中直接使用"孔"将表达式放在适当的位置:
var s = $"{p.Name} is {p.Age} year{{s}} old";与此一样
String.Format
,可以给出可选的对齐和格式说明符:var s = $"{p.Name,20} is {p.Age:D3} year{{s}} old";孔的内容几乎可以是任何表达式,包括其他字符串:
var s = $"{p.Name} is {p.Age} year{(p.Age == 1 ? "" : "s")} old";请注意,条件表达式是括号的,因此:"s"不会与格式说明符混淆.
通过
这是C#6的一个新功能,称为字符串插值,它
让您更轻松地格式化字符串.String.Format和它的表兄弟是非常通用的,但它们的使用有点笨重且容易出错.
有关这方面的更多信息,请查看此处.
例
让我们有以下课程:
public class Customer { public int Id { get; set; } public string FirstName {get; set;} public string LastName { get; set; } }
让我们假设我们想要ToString
方法,如下所示:
public override string ToString() { return string.Format("The customer with Id: {0} has as FirstName: {1} and as LastName: {2}", Id, FirstName, LastName); }
在C#6中,我们可以使用字符串插值获得相同的结果.
public override string ToString() { return $"The customer with Id: {Id} has as FirstName: {FirstName} and as LastName: {LastName}"; }
字符串插值的好处:
字符串比复合字符串更容易阅读.
由格式字符串后面的参数引起的语法错误减少,这些参数的顺序不正确,或者完全丢失并导致异常.