C# 未调用CustomFormatProvider

C# 未调用CustomFormatProvider,c#,.net,C#,.net,我有以下IFormatProvider和ICustomFormatter 使用系统; 利用制度全球化; 内部类LoggingFormatProvider:IFormatProvider { 公共对象GetFormat(类型formatType) { 变量isNumberFormatInfo=formatType==typeof(NumberFormatInfo); WriteLine(“formatType==typeof(NumberFormatInfo):{0}”,isNumberForma

我有以下
IFormatProvider
ICustomFormatter

使用系统;
利用制度全球化;
内部类LoggingFormatProvider:IFormatProvider
{
公共对象GetFormat(类型formatType)
{
变量isNumberFormatInfo=formatType==typeof(NumberFormatInfo);
WriteLine(“formatType==typeof(NumberFormatInfo):{0}”,isNumberFormatInfo);
如果(isNumberFormatInfo)
{
返回新的MyNumberFormatter();
}
其他的
{
返回null;
}
}
}
类MyNumberFormatter:ICustomFormatter
{
公共字符串格式(字符串格式、对象参数、IFormatProvider formatProvider)
{
var replaced=arg.ToString()
.替换(“1”、“1”)
.替换(“2”、“2”)
.替换(“3”、“3”)
.替换(“4”、“4”)
.替换(“5”、“5”)
.替换(“6”、“6”)
.替换(“7”、“7”)
.替换(“8”、“8”)
.替换(“9”、“9”)
.替换(“0”、“零”);
WriteLine(“返回:{0}”,已替换);
更换退货;
}
}
我这样调用它:

private static void Main()
{
var myLoggingProvider=新的LoggingFormatProvider();
Console.WriteLine(“使用string.Format()”);
var s=string.Format(myLoggingProvider,“123:{0:X}”,123);
控制台。写入线(s);
WriteLine(“返回:{0}”,s);
}
当我运行它时,
MyNumberFormatter.Format
不会被调用,而默认的数字格式化程序是(将
123
格式化为hex
7B

它输出:

使用string.Format()
formatType==typeof(NumberFormatInfo):False
formatType==typeof(NumberFormatInfo):True
123:7B
返回:123:7B

如果
MyLoggingFormatter
类型也实现了
ICustomFormatter
这样的话,我会得到同样的行为:

内部类LoggingFormatProvider:IFormatProvider、ICustomFormatter
{
公共对象GetFormat(类型formatType)
{
变量isNumberFormatInfo=formatType==typeof(NumberFormatInfo);
WriteLine(“formatType==typeof(NumberFormatInfo):{0}”,isNumberFormatInfo);
如果(isNumberFormatInfo)
{
//返回新的MyNumberFormatter();
归还这个;
}
其他的
{
返回null;
}
}
公共字符串格式(字符串格式、对象参数、IFormatProvider formatProvider)
{
var replaced=arg.ToString()
.替换(“1”、“1”)
.替换(“2”、“2”)
//等等。。。
.替换(“0”、“零”);
WriteLine(“返回:{0}”,已替换);
更换退货;
}
}

您需要更改以下内容:

var isNumberFormatInfo = formatType == typeof(NumberFormatInfo);
为此:

var isNumberFormatInfo = formatType == typeof(ICustomFormatter);

它会起作用的。

我想我已经弄明白了

formatType
是此格式化所需的类型。因此,如果它是一个
ICustomFormatter
,那么我需要返回一个
ICustomFormatter
,如果它是一个
NumberFormatInfo
,那么我需要返回一个
NumberFormatInfo

鉴于
NumberFormatInfo
是一个密封类,实际上不可能创建自定义类;因此,所有自定义格式,无论它们的目标是数字、日期还是其他格式,都需要使用
ICustomFormatter

如果它们不匹配,那么看起来实现只是回到了默认状态。这意味着MSDN上的示例实际上是误导性的,不需要条件检查,您只需返回
ICustomFormatter
的实现,框架将在可能的情况下使用它

(显然,您可能希望在那里设置条件值,只是为了减少分配的数量。)

给定当前CTS,
formatType
,只有三个可能的值:

  • NumberFormatInfo
  • DateTimeFormatInfo
  • ICustomFormatter
  • 如果您通过了第一个实例中的任何一个,则必须返回null,因为您无法构造自定义实例,所以让框架选择正确的实例


    如果你通过了第三个,你可能会变得疯狂。

    @Mate是的,如果我将
    ICustomFormatter
    实现复制到
    LoggingFormatProvider
    ,同样的行为。为什么你希望formatType==typeof(NumberFormatInfo)为真?@Dani,因为我正在传递一个整数进行格式化。该条件确实返回
    true
    。如果我运行您的代码,则formatType的类型为System.ICustomFormatter,因此false@Dani首先是
    ICustomFormatter
    ,然后是
    NumberFormatInfo
    。它被调用了两次。我缺少的信息是,返回的类型必须与传递到方法中的类型相匹配。