内插字符串(Visual Basic 引用)

用于构造字符串。 内插字符串类似于包含内插表达式的模板字符串。 内插字符串返回的字符串可替换内插表达式并且包含其字符串表示形式。 此功能在 Visual Basic 14 及更高版本中提供。

复合格式字符串相比,内插字符串的参数更易于理解。 例如,内插字符串

Console.WriteLine($"Name = {name}, hours = {hours:hh}")

包含 2 个内插表达式:“{name}”和“{hours:hh}”。 等效复合格式字符串为:

Console.WriteLine("Name = {0}, hours = {1:hh}", name, hours)

内插字符串的结构为:

$"<text> {<interpolated-expression> [,<field-width>] [:<format-string>] } <text> ..."

其中:

  • field-width 是一个带符号整数,表示字段中的字符数。 如果为正数,则字段右对齐;如果为负数,则左对齐。

  • “格式字符串”是适合正在设置格式的对象类型的格式字符串。 例如,对于 DateTime 值,它可能是标准的日期和时间格式字符串,例如“D”或“d”。

重要

字符串开头的 $" 之间不能有任何空格。 这样做会导致编译器错误。

可以在可使用字符串的任何位置使用内插字符串。 每次执行带内插字符串的代码时,都会计算内插字符串。 这有助于分隔内插字符串的定义和计算结果。

若要在内插字符串中包含大括号(“{”或“}”),请使用两个大括号,即“{{”或“}}”。 请参阅“隐式转换”部分以获取详细信息。

如果内插字符串包含在内插字符串中具有特殊意义的其他字符,例如引号 (")、冒号 (:) 或逗号 (,),则出现在文本中时应转义这些字符;如果它们是内插表达式中随附的语言元素,则应将其包括在由括号分隔的表达式内。 以下示例对引号进行转义,以将其包括在结果字符串中:

Public Module Example
   Public Sub Main()
      Dim name = "Horace"
      Dim age = 34
      Dim s1 = $"He asked, ""Is your name {name}?"", but didn't wait for a reply."
      Console.WriteLine(s1)
      
      Dim s2 = $"{name} is {age:D3} year{If(age = 1, "", "s")} old."
      Console.WriteLine(s2) 
   End Sub
End Module
' The example displays the following output:
'       He asked, "Is your name Horace?", but didn't wait for a reply.
'       Horace is 034 years old.

隐式转换

内插字符串有 3 种隐式类型转换:

  1. 将内插字符串转换为 String。 下例返回一个字符串,其内插字符串表达式已替换为字符串表示形式。 例如:

    Public Module Example
       Public Sub Main()
          Dim name = "Bartholomew"
          Dim s1 = $"Hello, {name}!"  
          Console.WriteLine(s1)
       End Sub
    End Module
    ' The example displays the following output:
    '      Hello, Bartholomew!
    ' </Snippet1>
    

    这是字符串解释的最终结果。 出现的所有双大括号(“{{”和“}}”)都转换为单大括号。

  2. 将内插字符串转换为 IFormattable 变量,使用此变量可通过单个 IFormattable 实例创建多个包含区域性特定内容的结果字符串。 对于包括诸如各区域性的正确数字和日期格式之类的内容,这种转换很有用。 出现的所有双大括号(“{{”和“}}”)仍保留为双大括号,直至通过显式或隐式调用 ToString() 方法格式化字符串。 包含的所有内插表达式都转换为 {0}、{1} 等。

    以下示例使用反射来显示内插字符串中所创建的 IFormattable 变量的成员以及字段和属性值。 并将 IFormattable 变量传递给 Console.WriteLine(String) 方法。

    Imports System.Globalization
    Imports System.Reflection
    
    Public Module Example
       Public Sub Main()
          Dim price = 1000
          Dim s2 As IFormattable = $"The cost of this item is {price:C}."  
          ShowInfo(s2)
          CultureInfo.CurrentCulture = New CultureInfo("en-US")
          Console.WriteLine(s2)
          CultureInfo.CurrentCulture = New CultureInfo("fr-FR")
          Console.WriteLine(s2)      
       End Sub
    
       Private Sub ShowInfo(obj As Object)
          Console.WriteLine($"Displaying member information:{vbCrLf}")
          Dim t = obj.GetType()
          Dim flags = BindingFlags.Public Or BindingFlags.Instance Or BindingFlags.Static Or BindingFlags.NonPublic
          For Each m In t.GetMembers(flags) 
             Console.Write($"   {m.Name} {m.MemberType}")   
             If m.MemberType = MemberTypes.Property Then
                Dim p = t.GetProperty(m.Name, flags)
                Console.Write($"   Value: {p.GetValue(obj)}")         
             End If
             If m.MemberType = MemberTypes.Field Then
                Dim f = t.GetField(m.Name, flags)
                Console.Write($"   Value: {f.GetValue(obj)}")
             End If
             Console.WriteLine()
          Next
          Console.WriteLine($"-------{vbCrLf}")
       End Sub
    End Module
    ' The example displays the following output:
    Displaying member information:
    
    '       get_Format Method
    '       GetArguments Method
    '       get_ArgumentCount Method
    '       GetArgument Method
    '       ToString Method
    '       System.IFormattable.ToString Method
    '       ToString Method
    '       Equals Method
    '       GetHashCode Method
    '       GetType Method
    '       Finalize Method
    '       MemberwiseClone Method
    '       .ctor Constructor
    '       Format Property   Value: The cost of this item is {0:C}.
    '       ArgumentCount Property   Value: 1
    '       _format Field   Value: The cost of this item is {0:C}.
    '       _arguments Field   Value: System.Object[]
    '       -------
    '
    '       The cost of this item is $1,000.00.
    '       The cost of this item is 1 000,00 €.
    ' </Snippet1>
    
    

    请注意,只能通过使用反射来检查内插字符串。 如果将其传递给字符串格式设置方法,例如 WriteLine(String),则会解析其格式项并返回结果字符串。

  3. 将内插字符串转换为表示复合格式字符串的 FormattableString 变量。 例如,检查复合格式字符串及其呈现为结果字符串的方式可能有助于在生成查询时防止注入攻击。 FormattableString 还包括:

    出现的所有双大括号(“{{”和“}}”)都保留为双大括号,直至格式化。 包含的所有内插表达式都转换为 {0}、{1} 等。

    Imports System.Globalization
    
    Public Module Example
       Public Sub Main()
          Dim name = "Bartholomew"
          Dim s3 As FormattableString = $"Hello, {name}!"  
          Console.WriteLine($"String: '{s3.Format}'")
          Console.WriteLine($"Arguments: {s3.ArgumentCount}")
          Console.WriteLine($"Result string: {s3}")
       End Sub
    End Module
    ' The example displays the following output:
    '       String: 'Hello, {0}!'
    '       Arguments: 1
    '       Result string: Hello, Bartholomew!
    
    

请参阅