如何委托默认格式提供程序?

时间:2012-07-11 17:25:58

标签: c# string-formatting

我想创建一个EscapingFormatProvider,在返回之前自动HTML转义格式化字符串,除非格式参数以!:

开头
string.Format(new EscapingFormatProvider(), "<div>{0}</div>", "<script src='foo'></script>");
// => <div>&lt;script src='foo'&gt;&lt;/script&gt;</div>

string.Format(new EscapingFormatProvider(), "<div>{0:!}</div>", "<script src='foo'></script>");
// => <div><script src='foo'></script></div>

我希望它传递格式参数,少了!如果有,则为默认格式化程序。唯一的麻烦是,我不知道如何获得默认的格式化程序。我发现的所有示例都没有解决委派默认格式化程序的问题。

编辑:这就是我提出的:

private class EscapingFormatProvider : IFormatProvider, ICustomFormatter
{
    public object GetFormat(Type formatType) { return this; }

    private string DefaultFormat(string format, object arg)
    {
        return string.Format("{0:" + format + "}", arg);
    }

    public string Format(string format, object arg, IFormatProvider formatProvider)
    {
        return (format.First() == '!')
            ? HttpUtility.HtmlEncode(DefaultFormat(format.Substring(1), arg))
            : DefaultFormat(format, arg);
    }
}

这有点间接,但我认为它有效。

2 个答案:

答案 0 :(得分:3)

正确的解决方案是重新实现默认格式化程序的功能,具体如下:

var formattable = arg as IFormattable;
return formattable == null
    ? arg.ToString()
    : formattable.ToString(format, formatProvider);

除此之外,如果ICustomFormatter是要求的类型,您的格式提供者应该只返回自己。

因此,在您的情况下,您的格式提供程序应如下所示:

class EscapingFormatProvider : IFormatProvider, ICustomFormatter
{
    public object GetFormat(Type formatType)
    {
        if (formatType == typeof(ICustomFormatter))
            return this;
        return null;
    }

    public string Format(string format, object arg, IFormatProvider formatProvider)
    {
        var escape = false;
        if (format.StartsWith("!"))
        {
            escape = true;
            format = format.Substring(1);
        }
        var formattable = arg as IFormattable;
        var formatted = formattable == null
            ? arg.ToString()
            : formattable.ToString(format, formatProvider);
        return escape ? HttpUtility.HtmlEncode(formatted) : formatted;
    }
}

答案 1 :(得分:1)

如果我正确理解你,你需要做的就是使用默认格式提供者调用不带IFormatProvider的string.Format的重载!或者你的意思是“默认格式化程序”,还是你担心本地化?