Question from one example in Item 5 《Effective C#》
1. Customer.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CSharp
{
class Customer:IFormattable
{
public string Name { get; set; }
public decimal Revenue { get; set; }
public string ContactPhone { get; set; }
string IFormattable.ToString(string format, IFormatProvider formatProvider)
{
if (formatProvider != null)
{
ICustomFormatter fmt = formatProvider.GetFormat(this.GetType()) as ICustomFormatter;
if (fmt != null)
{
return fmt.Format(format, this, formatProvider);
}
}
switch (format)
{
case "r":
return Revenue.ToString();
case "p":
return ContactPhone;
case "np":
return string.Format("{0,20}, {1,10:c}", Name, Revenue);
case "n":
case "G":
default:
return Name;
}
}
}
public class CustomFormatter : IFormatProvider
{
/// <summary>
///
/// </summary>
/// <param name="formatType"></param>
/// <returns></returns>
public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
return new CustomerFormatProvider();
return null;
}
//Nested class
private class CustomerFormatProvider : ICustomFormatter
{
public string Format(string format, object arg, IFormatProvider formatProvider)
{
Customer c = arg as Customer;
if (c == null)
{
return arg.ToString();
}
return string.Format("{0,50}, {1,15}, {2,10:C}", c.Name, c.ContactPhone, c.Revenue);
}
}
}
}
2. Program.cs
class Program
{
static void Main(string[] args)
{
Customer c1 = new Customer();
c1.Name = "qiqi";
c1.Revenue = 13000;
c1.ContactPhone = "1111111";
Console.WriteLine(string.Format(new CustomFormatter(), "", c1));
// Expected: call the nested class CustomerFormatProvider::Format in CustomFormatter.
// return qiqi, 1111111, ¥13,000.00
// But actual result is: empty.
// Why?
}
}