String.Format против int.ToString в отношении проблемы iCustomFormatter - PullRequest
5 голосов
/ 26 марта 2012

У меня есть следующие две строки кода:

var BadResult = (100).ToString("B", new CustomFormatter ());
var GoodResult = String.Format("{0}", 100, new CustomFormatter ());

Принимая во внимание, что BadResult явно плох, а GoodResult хорош.Мой класс CustomFormatter объявлен так: (также с одной функцией, которую я считаю уместной):

public class CustomFormatter 
               : IFormatProvider, ICustomFormatter
{
    public virtual Object GetFormat(Type formatType)
    {
        String formatTypeName = formatType.ToString();
        formatTypeName = formatTypeName;
        Object formatter = null;
        if (formatType == typeof(ICustomFormatter))
            formatter = this;
        return formatter;
    }
}

Сама проблема, когда я запускаю строку кода с «хорошим результатом», функция GetFormatэто запрос экземпляра CustomFormatter.

Всякий раз, когда он вызывается с помощью Float.Tostring (), он ожидает экземпляр NumberFormatInfo.

Сначала я переходил к «Мой CustomFormatter должен быть производным от NumberFormatInfo».К сожалению, класс запечатан.

Итак: Что мне нужно сделать, чтобы иметь возможность вызывать Float.ToString () с пользовательским форматером ?

Спасибо!

Ответы [ 2 ]

3 голосов
/ 26 марта 2012

Ваш

 var GoodResult = String.Format("{0}", 100, new CustomFormatter ());

не использует CustomFormatter. Таким образом, ваши хорошие результаты, кажется, достигнуты по умолчанию.

Что вы, вероятно, хотите:

 var GoodResult = String.Format(new CustomFormatter (), "{0}", 100);

Посмотрите, как это работает.

1 голос
/ 26 марта 2012

Я не уверен, что вы можете использовать собственный форматтер с Number.ToString. Все примеры, которые я видел с пользовательскими форматерами, используют String.Format ( это на MSDN , например).

Я предлагаю вам попробовать метод расширения:

public static class MyExt 
{
    public static string ToFormattedString(this float This, string format, IFormatProvider provider)
    {
        return String.Format(provider,"{0}", new object[] {This});
    }
}

//now this works
var NoLongerBadResult = (100F).ToFormattedString("B", new CustomFormatter ());

РЕДАКТИРОВАТЬ хорошо, я думаю, я понял. Вам нужно изменить текущий NumberFormatInfo и вернуть его из GetFormat:

public class CustomFormatter :  IFormatProvider, ICustomFormatter
{
    public object GetFormat(Type formatType)
    {
        if (formatType == typeof(ICustomFormatter))
            return this;
        else if(formatType == typeof(NumberFormatInfo))
        {
            NumberFormatInfo nfi = (NumberFormatInfo)NumberFormatInfo.CurrentInfo.Clone(); // create a copy of the current NumberFormatInfo
            nfi.CurrencySymbol = "Foo"; // change the currency symbol to "Foo" (for instance)
            return nfi; // and return our clone
        }
        else
            return null;
    }

    public string Format(string fmt, object arg, IFormatProvider formatProvider)
    {
        return "test";
    }
}

теперь это работает:

var NowItWorks = (100).ToString("C", new CustomFormatter ());
var GoodResult = String.Format(new CustomFormatter (),"{0}", 100);
Console.WriteLine(NowItWorks); // Foo 100.00
Console.WriteLine(GoodResult); // test
...