2012-03-26 63 views
4

我的代碼如下兩行:的String.Format VS int.ToString的問候iCustomFormatter問題

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功能requestng CustomFormatter的一個實例。

每當使用Float.Tostring()調用它時,它的期望NumberFormatInfo的一個實例。

我最初跳到「我的CustomFormatter應該從NumberFormatInfo派生」。不幸的是,這個班是封閉的。

因此:我需要做什麼才能用自定義格式化程序調用Float.ToString()?

謝謝!

回答

1

我不確定你可以使用Number.ToString的自定義格式化程序。我用自定義格式化程序看到的所有示例都使用String.Format(例如this on the 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()); 

編輯好吧,我想我得到了它。你需要從的getFormat改變當前的NumberFormatInfo並返回它:

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 
+0

從我的互聯網偵探工作中,這似乎開始看起來像解決方案。然而,爲什麼地獄是一個float.tostring()重載,允許你給一個icustomformatter? – greggorob64 2012-03-26 14:31:32

+0

@ greggorob64你是對的,它應該是可能的。 [Single.ToString](http://msdn.microsoft.com/en-us/library/6dx8etks.aspx)的文檔說「提供者參數是一個IFormatProvider實現,它的GetFormat方法返回一個NumberFormatInfo對象」,所以它看起來應該有一種方法來創建一個NumberFormatInfo對象並從您的自定義getformat中返回它。儘管...我還沒有找到辦法做到這一點但我仍然在嘗試 – 2012-03-26 14:43:26

+1

@ greggorob64 ok,所以...您的自定義提供程序工作正常,但是如果您將其與Number.Tostring一起使用,您只能使用NumberFormatProvider可以理解的格式,因此B不起作用(但如果您嘗試'(100).ToString(「C」,新的CustomFormatter());'它的工作原理和100被格式化爲貨幣)。例如,您可能會返回一個自定義的NumberFormatProvider,您可以在其中更改小數點的符號,但是您只能使用NumberFormatInfo自身允許您自定義的更改類型 – 2012-03-26 14:52:38

2

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

未使用的CustomFormatter。所以你的好結果似乎是通過默認來實現的。

你想要的可能是:

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

見是如何工作的。

+0

也許我問我的問題糟糕,我想BadResult工作。 – greggorob64 2012-03-26 14:01:40

+0

我需要(100.0).ToString(「{0}」,new CustomFormatter());上班。我有String.Format已經正常工作。 – greggorob64 2012-03-26 14:07:32

+0

這是不可能的。它採用IFormatProvider的唯一原因是允許傳遞CultureInfo。無論如何,它使用CultureInfo內部的NumberFormatInfo。所以唯一的Int.ToString類型可以接受的是NumberFormatInfo。 – Will 2012-03-26 14:22:48