Given I have a Meta Data resource string stored in my Database that will return like this:
var pageTitle = "Shop the latest {category1} Designer {category2} {category3} at www.abc.com";
And I want to replace the {placeholders}
with variable values
;
var category1 = "womenswear";
var category2 = "dresses";
var category3 = "cocktail dresses";
I have tried, with no luck;
var newTitle = $"pageTitle, category1, category2, category3";
var newTitle = $(pageTitle, category1, category2, category3);
I know that I could use string.Replace()
that has a performance overhead. Does anyone know how this can be done efficiently using the latest C# string interpolation?
String interpolation is a technique that enables you to insert expression values into literal strings. It is also known as variable substitution, variable interpolation, or variable expansion. It is a process of evaluating string literals containing one or more placeholders that get replaced by corresponding values.
WriteLine("Hello, {0}! Today is {1}, it's {2:HH:mm} now.", name, date. DayOfWeek, date); // String interpolation: Console. WriteLine($"Hello, {name}!
Syntax of string interpolation starts with a '$' symbol and expressions are defined within a bracket {} using the following syntax. Where: interpolatedExpression - The expression that produces a result to be formatted.
In expressions, place quotes around the parameter reference ${param-name} when you want that parameter's value to be resolved as a string. For example: To use the value of <operator-parameter name="starter" value="hundred"/> as a string in an expression, reference the parameter as: "${starter}" .
You can't use string interpolation here. String interpolation is a compile-time rewrite method for string.Format
, which is the solution you should use:
var newTitle = string.Format("{0}, {1}, {2}, {3}", pageTitle, category1, category2, category3);
Or string.Join
:
var newTitle - string.Join(", ", new string[] { pageTitle, category1, category2, category3 });
Since you are loading from database, it might be just better in your case to keep using string.Replace
.
I know that I could use string.Replace() that has a performance overhead
Of mere nanoseconds. You shouldn't optimize prematurely.
As said, the C# 6 string interpolation feature happens at compile-time. If you want to do this at runtime, you'll have to use string replacement.
I assume your strings are formatted like that for ease of editing and not having a fixed replacement order, so simply do this:
var input = "Shop the latest {category1} Designer {category2} {category3} at www.abc.com";
var category1 = "womenswear";
var category2 = "dresses";
var category3 = "cocktail dresses";
var result = input.Replace("{category1}", category1)
.Replace("{category2}", category2)
.Replace("{category3}", category3);
This will just work. You could also store your replacement values in a dictionary, and loop over the keys to replace the key with the value.
Although .NET does not offer a built-in capability for this, you can easily build a pretty good implementation with regex:
public static string Format(string formatWithNames, IDictionary<string,object> data) {
int pos = 0;
var args = new List<object>();
var fmt = Regex.Replace(
formatWithNames
, @"(?<={)[^}]+(?=})"
, new MatchEvaluator(m => {
var res = (pos++).ToString();
var tok = m.Groups[0].Value.Split(':');
args.Add(data[tok[0]]);
return tok.Length == 2 ? res+":"+tok[1] : res;
})
);
return string.Format(fmt, args.ToArray());
}
The idea is to replace names with consecutive numbers (see sb.Append(pos++)
), build an array of object parameters (see args.Add(data[tok[0]])
), and pass the result to string.Format
to use string
's formatting capabilities.
Now you can pass your resource to this Format
, along with a dictionary of key-value pairs, and get a string formatted using .NET's built-in formatting capabilities:
var x = new Dictionary<string,object> {
{"brown", 1}
, {"jumps", 21}
, {"lazy", 42}
};
Console.WriteLine("{0}", Format("Quick {brown} fox {jumps:C} over the {lazy:P} dog", x));
Note that there is no $
in front of the string literal, so there's no C#'s built-in interpolation going on here.
This prints
Quick 1 fox $21.00 over the 4,200.00 % dog
The approach is based on the idea by Scott Hanselman, except formatting is done differently.
Demo.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With