所以,我刚刚与the comments section中的用户进行了以下对话。
我:
Year year = new Year{ State = States.Happy };
他们:
eventStream.ReceiveJoke += joke =>
Console.WriteLine($"Pretty nice joke: {joke}, Thanks!!!");
而且,就像我一样,我不知道他对美元符号的意思,但我觉得问他是太尴尬了。
答案 0 :(得分:36)
这是一个内插的字符串文字,在C#6中引入。
它大致相当于:
eventStream.ReceiveJoke += joke =>
Console.WriteLine(string.Format("Pretty nice joke: {0}, Thanks!!!", joke));
编译器在$
引入的任何字符串文字中查找大括号,并对其应用字符串格式。您可以使用(大多数)任意表达式,而不仅仅是变量,例如
Console.WriteLine($"{year.State} {2000 + 16}"); // Happy 2016
答案 1 :(得分:24)
这是允许你创建插值字符串的符号,它是C#6的新功能,我喜欢它。
它也是一个Syntax Sugar,我将在最后解释它的含义。
public string Receive(int value)
{
return String.Format("Received: {0}", value);
}
public string Receive6(int value)
{
return $"Received: {value}";
}
他们将具有相同的IL实现,从接收
看这里的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
在另一个代码中转换您编写的语法。 p>
是的,你可以,看下面
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是完全一样的事情
答案 2 :(得分:8)
简而言之,这是提高代码可读性并缩短代码长度的好方法。它比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"不会与格式说明符混淆。
答案 3 :(得分:5)
这是C#6的一个新功能,称为字符串插值,
可让您更轻松地格式化字符串。 String.Format及其堂兄是 非常通用,但它们的使用有点笨重且容易出错。
有关此问题的详细信息,请查看here。
示例强>
让我们有以下课程:
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}";
}
字符串插值的好处: