您似乎誤解了.NET Framework格式化基礎架構的設計。 ICustomFormatter
不應在IFormattable.ToString
的實現中引用,因爲它與該接口的預期用途相沖突。
IFormattable
的對象應該只實現IFormattable
如果它知道如何格式化本身(理想情況下,應該委派到另一個類的課程,但這裏會有故意耦合)。一個對象可能知道如何以多種不同的方式進行格式化,所以格式字符串允許你在它們之間進行選擇。即使如此,仍然可能會丟失信息,這些信息因文化而異。因此,有第二個參數間接提供這些信息。
傳遞給IFormatProvider.GetFormat
的類型是打算成爲IFormatProvider
提供給該類的特定類型或接口。
例如,內置的數字類型希望能夠檢索System.Globalization.NumberFormatInfo
的實例,而DateTime
相關的類希望能夠檢索System.Globalization.DateTimeFormatInfo
。
實施IFormattable
讓我們想象一下,我們正在創造一些新的自我格式化類。如果它只知道一種格式化的方法,它應該簡單地覆蓋object.ToString()
,僅此而已。如果班級知道不止一種格式化方式應該執行IFormattable
。
的format
參數
每IFormattable.ToString
the documentation的"G"
格式字符串(其表示的一般格式)必須得到支持。建議將null或空格式的字符串與"G"
的格式字符串等效。確切的意義在其他方面取決於我們。
的formatProvider
參數
如果我們需要什麼特定的文化,或否則將發生變化,我們需要利用IFormatProvider
參數。我們會使用IFormatProvider.GetFormat
來請求某種類型。如果IFormatProvider
爲空,或者IFormatProvider.GetFormat
對於我們想要的類型返回null,我們應該回退到某些默認源以獲取此不同信息。
默認來源不需要是靜態的。可以想象,默認來源可能是應用程序中的用戶設置,並且formatProvider
用於預覽選項更改和/或當序列化需要固定格式時。
也有可能格式化可能涉及格式化一些子對象。在這種情況下,您可能想要通過IFormatProvider
。 MSDN有一個excellent example實施IFormattable
表明這種情況。
其他ToString
重載
在實施IFormattable
重要的是,Object.ToString()
的方式相當於覆蓋以下
public override string ToString()
{
return this.ToString(null, System.Globalization.CultureInfo.CurrentCulture);
}
這樣做可以確保somestring + yourobject
相當於string.Format("{0}{1}",somestring, yourobject)
,您的用戶會期望是真實的。
爲方便您的用戶,您應該提供string ToString(string format)
。此外,如果您的默認格式具有可從IFormatProvider
獲益的任何不同組件,您可能還需要提供public string ToString(IFormatProvider provider)
。
ICustomFormatter
所以,我們應該做些什麼,如果我們想格式化的一類,不知道怎麼給自己格式化,或者我們要使用不是由類本身支持的某種格式。這就是ICustomFormatter變得相關的地方。可以提供ICustomFormatter
類型的IFormatProvider
可以在諸如string.Format
和StringBuilder.AppendFormat
的方法中作爲IFormatProvider
參數傳遞。
提供的ICustomFormatter
對string.Format
所做的每種格式都要求其Format
方法。如果ICustomFormatter
不熟悉所使用的格式字符串或不支持該類型,那麼它只是代表IFormattable.ToString
或Object.ToString
。如果您格式化尚未提供格式支持的對象,則ICustomFormatter
documentation提供了所需內容的列表,如果您只想向現有的IFormattable
添加額外格式,則需要什麼。它還提供了添加額外格式大小寫的例子。
參考
This MSDN page提供了.NET格式化系統的一個很好的概述,並提供鏈接到MSDN幾乎所有的其他相關網頁。這是幾乎所有與格式相關的問題開始的最佳位置。
感謝您的詳細解答和參考! –
當我第一次看到這個問題時,我基本上和以前一樣對所有這些都感到困惑,所以我看着反射器的框架,開始閱讀MSDN頁面,而我只是更加困惑。在我找到主要參考頁面之前,我已經閱讀了大部分MSDN頁面。即使如此,它開始點擊之前花了一段時間。有一些棘手的部分。例如,我懷疑'ICustomFormatter'與IFormatProvider一起使用的唯一原因是因爲它是1.0框架的一個晚期附加,並且他們不想添加新的'string.Format'重載。 –