Dop il ICustomFromatter per scrivere numeri in lettere, ecco un’altro FormatProvider per scrivere un numero intero da cifre arabe in cifre romane:
public class RomanFormatProvider : IFormatProvider, ICustomFormatter { IFormatProvider _parent; public RomanFormatProvider() : this(CultureInfo.CurrentCulture) { } public RomanFormatProvider(IFormatProvider parent) { _parent = parent; } public object GetFormat(Type formatType) { if (formatType == typeof(ICustomFormatter)) return this; return null; } public string Format(string format, object arg, IFormatProvider prov) { if (arg == null || format != "RO") return string.Format(_parent, "{0:" + format + "}", arg); return ToRoman(arg.ToString()); } private string ToRoman(string n) { StringBuilder r = new StringBuilder(); int i = 0; foreach (var c in n) { r.Append(calcDigit(int.Parse(c.ToString()), n.Length - i - 1)); i++; } return r.ToString(); } class Level { public Level(string i, string v, string x) { this.i = i; this.v = v; this.x = x; } public string i { get; set; } public string v { get; set; } public string x { get; set; } } static Level[] levels = new RomanFormatProvider.Level[] { new Level("I", "V", "X"), new Level("X", "L", "C"), new Level("C", "D", "M") }; string calcDigit(int d, int l) { string str; if (l > 2) { str = ""; for (var k = 1; k <= d * Math.Pow (10, l - 3); k++) str += "M"; return str; } else switch (d) { case 1: return levels[l].i; case 2: return levels[l].i + levels[l].i; case 3: return levels[l].i + levels[l].i + levels[l].i; case 4: return levels[l].i + levels[l].v; case 5: return levels[l].v; case 6: return levels[l].v + levels[l].i; case 7: return levels[l].v + levels[l].i + levels[l].i; case 8: return levels[l].v + levels[l].i + levels[l].i + levels[l].i; case 9: return levels[l].i + levels[l].x; default: return ""; } } }
Con questo CustomFormatter è possibile scrivere semplicemente:
RomanFormatProvider fr = new RomanFormatProvider(); s = string.Format(fr, "Il numero {0} in lettere è {0:RO}", 1971); Console.WriteLine(s);
Il cui output è:
Il numero 1971 in lettere è MCMLXXI