简体   繁体   English

VB.NET 14变量变量内插字符串

[英]VB.NET 14 Variable variable interpolated string

In VS 2015 / VB.NET 14 you can do some pretty cool stuff with string interoplation for example: 在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

But what if the string format is variable/configurable? 但是,如果字符串格式是可变的/可配置的,该怎么办? How can I do something like this: 我该如何做这样的事情:

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

I am using .NET 4 我正在使用.NET 4

Do not forget that interpolated strings are only syntax sugar for String.Format() . 不要忘记,插值字符串只是String.Format()语法糖。

So whenever things need to go more complex, simply return to use of 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")

Or do you think that interpolated string in interpolated string adds any special comfort to your code? 还是您认为插值字符串中的插值字符串为您的代码增添了特殊的舒适感? I'd say no. 我会说不。

An interpolated string has to be hard-coded, because it needs to be parsed by the compiler. 插值的字符串必须进行硬编码,因为它需要由编译器进行解析。

My NString library has a StringTemplate class that does something similar to string interpolation, but at runtime rather that at compile time: 我的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);

It's not exactly what you're asking, but it might help. 这并不是您要问的,但可能会有所帮助。

Just write a helper function and pass in the required argument: 只需编写一个辅助函数并传递所需的参数即可:

Public Function GetString(arg1 As String, arg2 As String) As String
    Return $"{arg1} {dict1(arg2)}"
End Function
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

interpolated strings are a "Compile time" feature. 插值字符串是“编译时”功能。 So they won't work with runtime variables. 因此,它们将无法与运行时变量一起使用。

Consider this code: 考虑以下代码:

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

The second line compiles to this IL: 第二行编译为此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)

Translated back to VB this would be: 转换回VB将是:

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

This means that interpolated strings do not exist at runtime! 这意味着插值字符串在运行时不存在! You can't use the funk in user adjustable variables.. 您不能在用户可调变量中使用放克。

I am actually happy about that.. otherwise this would be a MAJOR 'code execution injection security hole!' 我对此真的很满意..否则,这将是一个重大的“代码执行注入安全漏洞!”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM