DemoBytom
DemoBytom

Reputation: 305

Format string with meaningful markers

I used have a template string, read from DB and or text file:

var template="Your order {0} has dispatched from {1}, ETA {2:HH:MM dd.MM.yyyy}";

And then used string.Format(template, orderNo, warehouse, eta) to inject correct values.

Now, a business decision was made, to change those templates to use more meaningful markers:

var template="Your order {orderNo} has dispatched from {warehouse}, ETA {eta:HH:MM dd.MM.yyyy}";

And now I'm not sure what would be the best way to inject values, taking into consideration that, for example, eta field has formatting that is "hardcoded" into template (so that we could use different DateTime format depending on language)

One idea was to load the template into StringBuilder, replace named variables into set of {0}, {1}.. etc, And then use old string.Format method, but it's not really scalable and pain in the back to write all the boilerplate.

var formatTemplate = new StringBuilder(template)
    .Replace("{orderNo}", "{0}")
    .Replace("{warehouse}", "{1}")
    .Replace("{eta","{2")
    .ToString();
return string.Format(template, orderNo, warehouse, eta)

Is there a better way to do it? Maybe a way to read the template as interpolated string? The string is read from an outside source so I cannot simply use the $"{marker}" mechanic.

Upvotes: 1

Views: 1119

Answers (2)

dsdel
dsdel

Reputation: 1062

Please check out SmartFormat which in effect will do what you want to.

(You sayed, that you do not use replacing the human readable names with the indexes)

Example from their wiki:

String.Format references all args by index:

String.Format("{0} {1}", person.FirstName, person.LastName)

Smart.Format takes this a step further, and lets you use named placeholders instead:

Smart.Format("{FirstName} {LastName}", person)

In fact, Smart.Format supports several kinds of expressions:

Smart.Format("{FirstName.ToUpper} {LastName.ToLower}", person)

Working example requires the variables to be packed into an anonymous type:

var formatted=Smart.Format(template, new { orderNo, warehouseName, eta })

that returns correct, desired, result, with markers correctly replaced. Without the anonymous type it didn't seem to work.

Upvotes: 2

Praneet Nadkar
Praneet Nadkar

Reputation: 813

You can use string interpolation if your framework supports: Have a look at this: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/interpolated-strings

You can then update your code something like:

 var orderNo = 1;
 var warehouse = "Trinidad";
 var template = $"Your order {orderNo} has dispatched from {warehouse}";

Upvotes: -1

Related Questions