在遵循 Format TimeSpan in DataGridView column 之后,我试图弄清楚 IFormatProvider 和 ICustomFormatter 是如何工作的关于如何在 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()
除了 DateTimeFormatInfo
或 CultureInfo
将不接受任何东西,如果对象不是这些类型,即使它实现了 ICustomFormatter
- https://stackoverflow.com/a/2382481/492336 .
所以我的问题是,这是否适用于 ToString()
方法的所有情况?它是否也适用于 DataGridView,在哪些情况下我可以传递真正自定义的格式化程序?
最佳答案
当您对整数调用 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;
}
所以你看看是否所有其他方法都失败了,它调用类型等于 NumberFormatInfo
的 GetFormat
,并期望返回 NumberFormatInfo
。您不会从 GetFormat
返回它,因此它使用默认格式化程序(当前 cutlure)。在这种情况下使用它的有效方法是这样的:
class MyFormatter : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
if (formatType == typeof(NumberFormatInfo)) {
return new NumberFormatInfo()
{
// something here
};
}
Console.WriteLine("GetFormat");
return this;
}
public string Format(string format, object arg, IFormatProvider formatProvider)
{
Console.WriteLine("Format");
return "foo";
}
}
但我怀疑您是否可以通过这种方式为任何数字返回任意值,例如“foo”。
关于c# - 尝试实现自定义格式化程序,但从未调用 ICustomFormatter.Format,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39871955/