$-运算符对字符串应该意味着什么

本文关键字:意味着 什么 字符串 运算符 | 更新日期: 2023-09-27 18:28:36

所以,我刚刚在评论部分与用户进行了以下对话。

我:

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 中的一个新功能,我喜欢它。

这也是一个语法糖,最后我会解释它的含义。

让我们看看实际操作。 查看以下代码

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

现在让我们从 Receive6 查看 IL(在调试模式下,未优化(

.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几乎是一样的。

现在让我们了解什么是语法 Suggar

在计算机科学中,句法糖是编程语言中的语法,旨在使事物更易于阅读或表达。它使语言对人类使用来说"更甜蜜":事物可以更清晰、更简洁地表达,或者以一些人可能喜欢的替代风格表达。

从 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.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; }
}

假设我们想要 ovveride 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}";
}

字符串插值的优点:

    字符串
  • 比复合字符串更容易阅读。
  • 由于
  • 格式字符串后面的参数顺序不正确或完全缺失并导致异常而导致的语法错误有所减少。