[Money Pattern] Formatting
Calling ToString method will shows the amount value without any currency symbol/name/ISO code. In order to show the correct money formatting we have two choices:
- Define a static formatting rule
- Create a custom formatter
Personally I prefer the second option so that the user (of the Money class) can decide which formatting to use in any context. Consider to build a custom formatter:
public class CurrencyFormatInfo : IFormatProvider, ICustomFormatter
{
private const string FORMAT_NAME = "mn";
private const string FORMAT_SYMBOL = "ms";
private const string FORMAT_ISO = "mi";
public object GetFormat(Type formatType)
{
if (formatType != typeof(ICustomFormatter))
return null;
else
return this;
}
public string Format(string format, object arg, IFormatProvider formatProvider)
{
if (arg == null) throw new ArgumentNullException("arg");
if((!string.IsNullOrEmpty(format)) && (arg is Money))
{
string s = format.Trim().ToLower();
if (s.StartsWith("m"))
return FormatMoney(arg as Money, format, formatProvider);
}
if (arg is IFormattable)
return ((IFormattable)arg).ToString(format, formatProvider);
else return arg.ToString();
}
private string FormatMoney(Money m, string format, IFormatProvider formatProvider)
{
switch (format)
{
case FORMAT_NAME:
return string.Concat(m.Amount.ToString(formatProvider), " ", m.Currency.Name);
case FORMAT_ISO:
return string.Concat(m.Amount.ToString(formatProvider), " ", m.Currency.ISOCode);
case FORMAT_SYMBOL:
return string.Concat(m.Amount.ToString(formatProvider), " ", m.Currency.Symbol);
default:
return m.Amount.ToString(formatProvider);
}
}
}
In the above sample I defined three basic format strings, it is clear that in real-world situations you could decide to create more (and complex) choices. Once the format provider is defined we can then create all our ToString overrides:
public override string ToString()
{
return (new CurrencyFormatInfo()).Format("m", this, null);
}
public string ToString(string format)
{
return (new CurrencyFormatInfo()).Format(format, this, null);
}
public string ToString(string format, IFormatProvider formatProvider)
{
if (string.IsNullOrEmpty(format))
format = "m";
return (new CurrencyFormatInfo()).Format(format, this, formatProvider);
}