How to create custom string formatters with C# .NET
April 13, 2017 Leave a comment
.NET has a fairly large number of built-in string formatters that you can pass into the string.Format method. Here are some examples from the MSDN page about formatting:
String.Format("{0,-12}{1,8:yyyy}{2,12:N0}{3,8:yyyy}{4,12:N0}{5,14:P1}", city.Item1, city.Item2, city.Item3, city.Item4, city.Item5, (city.Item5 - city.Item3)/ (double)city.Item3); String.Format("{0,-12}{1,8}{2,12}{1,8}{2,12}{3,14}\n", "City", "Year", "Population", "Change (%)"); String.Format("{0,-10:C}", 126347.89m);
The IFormatProvider and ICustomFormatter interfaces will provide you with the methods required to create your own formats.
The IFormatProvider requires you to implement one method: GetFormat which returns the object that provides the custom formatting. This is even implied by the name of the interface: “format” and “provider”. It generally returns an object that implements the ICustomFormatter interface.
Let’s say you’d like to capitalise all characters in a string. You can of course use the ToUpper() method but this is an easy entry point into this exercise. Here comes our IFormatProvider object:
public class CapitalisationFormatProvider : IFormatProvider { public object GetFormat(Type formatType) { if (formatType == typeof(ICustomFormatter)) { return new CapitalisationCustomFormatter(); } return null; } }
…and here’s the CapitalisationCustomFormatter object:
public class CapitalisationCustomFormatter : ICustomFormatter { public string Format(string format, object arg, IFormatProvider formatProvider) { return arg.ToString().ToUpper(); } }
Let’s try this in action:
string toBeCapitalised = "i'm too lazy to capitalise these letters."; string capitalisedVersion = string.Format(new CapitalisationFormatProvider(), "New version: {0}", toBeCapitalised);
“capitalisedVersion” will be
New version: I’M TOO LAZY TO CAPITALISE THESE LETTERS.
If you provide more string arguments to the params array then all of them will be capitalised:
string toBeCapitalised = "i'm too lazy to capitalise these letters."; string capitalisedVersion = string.Format(new CapitalisationFormatProvider(), "New version: {0}, {1}, {2}", toBeCapitalised, "hello", "good bye");
“capitalisedVersion” will now become
New version: I’M TOO LAZY TO CAPITALISE THESE LETTERS., HELLO, GOOD BYE
What if you’d like to denote the capitalisation formatting in a special way and not apply it to all params elements automatically? You can use the “:” operator inside the placeholders much the same way as :C or :yyyy are used in the above examples from MSDN:
string toBeCapitalised = "i'm too lazy to capitalise these letters."; string capitalisedVersion = string.Format(new CapitalisationFormatProvider(), "New version: {0:cap}, {1}, {2:cap}", toBeCapitalised, "hello", "good bye");
We intend to apply the capitalisation to the first and last elements of the params arguments. We need to modify the CapitalisationCustomFormatter object slightly:
public class CapitalisationCustomFormatter : ICustomFormatter { public string Format(string format, object arg, IFormatProvider formatProvider) { if (format == "cap") { return arg.ToString().ToUpper(); } return arg.ToString(); } }
Check out the if statement where we see if the format is equal to “cap”. capitalisedVersion will now become
New version: I’M TOO LAZY TO CAPITALISE THESE LETTERS., hello, GOOD BYE
View all posts related to string and text operations here.