VB.NET 14变量插值字符串

时间:2015-10-26 09:51:21

标签: .net vb.net

在VS 2015 / VB.NET 14中,您可以使用字符串互换做一些很酷的事情,例如:

Dim str1 As String = "Hello"
Dim dict1 As New Dictionary(Of String, String)
dict1.Add("Area", "World")

Dim output As String = $"{str1} {dict1("Area")}"
Console.WriteLine(output)


>Hello World

但是如果字符串格式是可变的/可配置的呢?我怎么能这样做:

Dim str1 As String = "Hello"
Dim dict1 As New Dictionary(Of String, String)
dict1.Add("Area", "World")

Dim format = getStringFormat()
Dim output As String = $format
Console.WriteLine(output)


>World Hello

我正在使用.NET 4

5 个答案:

答案 0 :(得分:2)

不要忘记插值字符串只是String.Format()的语法糖。

因此,只要事情需要变得更加复杂,只需返回使用String.Format()

 
Dim format1 As String = "{0} {1}"
Dim format2 As String = "{1} {0}"

Dim string1 As String = String.Format(format1, "Hello", "World")
Dim string2 As String = String.Format(format2, "Hello", "World")

' now your case: format string created as result of another format string
Dim stringComplex As String = String.Format(
                                        String.Format("{0} {1}", format1, format2), 
                                        "Hello", 
                                        "World")

或者您认为插值字符串中的插值字符串会为您的代码添加任何特殊的舒适度吗?我会说不。

答案 1 :(得分:1)

插值字符串必须是硬编码的,因为它需要由编译器解析。

我的NString库有一个StringTemplate类,类似于字符串插值,但在运行时而不是在编译时:

var joe = new Person { Name = "Joe", DateOfBirth = new DateTime(1980, 6, 22) };
string text = StringTemplate.Format("{Name} was born on {DateOfBirth:D}", joe);

这不完全是你问的问题,但它可能有所帮助。

答案 2 :(得分:1)

只需编写辅助函数并传入必需的参数:

Public Function GetString(arg1 As String, arg2 As String) As String
    Return $"{arg1} {dict1(arg2)}"
End Function

答案 3 :(得分:0)

Sub Main()
    Dim variables As New Dictionary(Of String, Object) From {
        {"Country", "USA"},
        {"IpAddress", "8.8.8.8"},
        {"evtCount", 5},
        {"username", "Admin"}
    }

    Dim template As String = "{IpAddress}, {country}, {username}, {evtCount} DNS queries. {Country} (different case...)"
    Console.WriteLine(template)
    Console.WriteLine()

    Console.WriteLine(VariableStringInterpolation(template, variables))

    Console.WriteLine()
    Console.ReadKey()

End Sub

Public Function VariableStringInterpolation(
                                   template As String,
                                   variables As Dictionary(Of String, Object)
                                   ) As String

    Dim returValue As String = template

    For Each item As KeyValuePair(Of String, Object) In variables
        returValue = ReplaceCaseInsensitive(returValue, "{" & item.Key + "}", item.Value.ToString)
    Next

    Return returValue

End Function

Public Function ReplaceCaseInsensitive(template As String, target As String, replacement As String) As String

    Dim returValue As String = template
    Dim rx As Text.RegularExpressions.Regex

    rx =
        New Text.RegularExpressions.Regex(
        target,
        Text.RegularExpressions.RegexOptions.IgnoreCase)

    returValue = rx.Replace(template, replacement)

    Return returValue

End Function

答案 4 :(得分:0)

插值字符串是“编译时”功能。因此它们将无法与运行时变量一起使用。

考虑以下代码:

Dim f As New Test With {.A = 1, .B = 2, .C = 3}
Dim str = $"{f.A},{f.B},{f.C}"

第二行编译为此IL:

IL_001f: ldstr "{0},{1},{2}"
IL_0024: ldloc.0
IL_0025: callvirt instance int32 GeneralTest/Test::get_A()
IL_002a: box [mscorlib]System.Int32
IL_002f: ldloc.0
IL_0030: callvirt instance int32 GeneralTest/Test::get_B()
IL_0035: box [mscorlib]System.Int32
IL_003a: ldloc.0
IL_003b: callvirt instance int32 GeneralTest/Test::get_C()
IL_0040: box [mscorlib]System.Int32
IL_0045: call string [mscorlib]System.String::Format(string,  object,  object,  object)

翻译回VB将会是:

Dim str As String = String.Format("{0},{1},{2}", f.A, f.B, f.C)

这意味着插值字符串在运行时不存在!您不能在用户可调整的变量中使用funk。

对此我真的很高兴..否则,这将是一个重大的“代码执行注入安全漏洞!”