尝试实现自定义格式化程序,但从不调用ICustomFormatter.Format

时间:2016-10-05 10:49:14

标签: c# iformatprovider

我试图弄清楚IFormatProvider和ICustomFormatter如何在Format TimeSpan in DataGridView column之后如何在DataGridView中自定义TimeSpan。我创建了一个完全自定义的格式化程序,无论格式化是什么,它总是返回“foo”。

我在Int上使用它,但我认为它应该适用于所有类型,因为它不检查传递的值,它只返回"foo"

class MyFormatter : IFormatProvider, ICustomFormatter
{
    public object GetFormat(Type formatType)
    {
        Console.WriteLine("GetFormat");
        return this;
    }

    public string Format(string format, object arg, IFormatProvider formatProvider)
    {
        Console.WriteLine("Format");
        return "foo";
    }
}

我将它传递给int.ToString()

int number = 10;
Console.WriteLine(number.ToString(new MyFormatter()));

我得到的是:

GetFormat
10

虽然我希望得到的是:

GetFormat
Format
foo

修改:我找到了How to create and use a custom IFormatProvider for DateTime?,其中的答案是DateTime.ToString()除了DateTimeFormatInfoCultureInfo之外不会接受任何内容如果它不是这些类型,即使它实现ICustomFormatter - https://stackoverflow.com/a/2382481/492336,也会被拒绝。

那么我的问题是在ToString()方法的所有情况下都适用吗?它是否也适用于DataGridView,在哪些情况下我可以传递真正的自定义格式化程序?

2 个答案:

答案 0 :(得分:1)

当您在整数上调用ToString并提供IFormatProvider时,它会尝试从中提取 NumberFormatInfo ,大​​致如下:

public static NumberFormatInfo GetInstance(IFormatProvider formatProvider)
{
  CultureInfo cultureInfo = formatProvider as CultureInfo;
  if (cultureInfo != null && !cultureInfo.m_isInherited)
    return cultureInfo.numInfo ?? cultureInfo.NumberFormat;
  NumberFormatInfo numberFormatInfo = formatProvider as NumberFormatInfo;
  if (numberFormatInfo != null)
    return numberFormatInfo;
  if (formatProvider != null)
  {
    NumberFormatInfo format = formatProvider.GetFormat(typeof (NumberFormatInfo)) as NumberFormatInfo;
    if (format != null)
      return format;
  }
  return NumberFormatInfo.CurrentInfo;
}

因此,如果其他所有内容都失败,则会调用类型等于GetFormat的{​​{1}},并期望NumberFormatInfo返回。您不会从NumberFormatInfo返回它,因此它使用默认格式化程序(当前cutlure)。在这种情况下使用它的有效方法是:

GetFormat

但是这样我怀疑你可以为任何数字返回像“foo”这样的任意值。

答案 1 :(得分:-2)

实际上ToString()函数接受IFormatProvider作为其签名的参数:

ToString(IFormatProvider)
ToString(String)
ToString(String,IFormatProvider)

和IFormatProvider只有GetFormat(Type)函数才能实现。 ToString()不使用具有ICustomFormatter功能的Format()。所以 IFormatProvider的实施是:

class MyFormatter : IFormatProvider
    {
        public object GetFormat(Type formatType)
        {
            Console.WriteLine("GetFormat");
            return this;
        }    
    }