0

In VS 2015 / VB.NET 14 you can do some pretty cool stuff with string interoplation for example:

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

5 Answers 5

2

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:

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.

Sign up to request clarification or add additional context in comments.

Comments

2

Do not forget that interpolated strings are only syntax sugar for String.Format().

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

1 Comment

It would be usefull as the string format is configurable. So when changing the setting using {propA} {propB} instead of {0} {1} would be a bit easier to use.
1

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

Comments

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

Comments

0

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_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:

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!'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.