2016-02-23 57 views
3

C#中的字符串格式化;C#中的自定義字符串格式化程序#

我可以使用它嗎?是。

我可以實現自定義格式嗎?編號

我需要寫一些東西,我可以通過一組自定義格式選項string.Format,這將對特定項目有一定的影響。

在現階段,我有這樣的事情:

string.Format("{0}", item); 

,但我希望能夠做的事情與項目:

string.Format("{0:lcase}", item); // lowercases the item 
string.Format("{0:ucase}", item); // uppercases the item 
string.Format("{0:nospace}", item); // removes spaces 

我知道我可以做的事情一樣.ToUpper().ToLower()等等,但我需要做與字符串格式。

我一直在尋找諸如IFormatProviderIFormattable之類的東西,但我不知道它們是我應該使用的東西,還是如何實現它們。

任何人都可以解釋我怎麼能解決這個問題?

理由(以防萬一你想知道...)

我有一個小程序,在那裏我可以輸入一個逗號分隔值的集合,和模板。將這些項目與創建輸出的模板一起傳遞到string.Format。我想提供模板格式選項,以便用戶可以控制他們希望輸出項目的方式。

+1

'item'有什麼類型?請參閱[String.Format - 它如何工作以及如何實現自定義格式字符串](http://stackoverflow.com/questions/10512349/string-format-h​​ow-it-works-and-how-to-implement-custom-formatstrings )。 – CodeCaster

+0

@CodeCaster項目是一個字符串(請參閱理由) – series0ne

+0

[ICustomFormatter](https://msdn.microsoft.com/en-us/library/system.icustomformatter(v = vs.110).aspx) –

回答

8

您可以自定義格式,是這樣的:

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

    public string Format(string fmt, object arg, IFormatProvider formatProvider) 
    { 
     if(arg == null) return string.Empty; 

     if(fmt == "lcase") 
      return arg.ToString().ToLower(); 
     else if(fmt == "ucase") 
      return arg.ToString().ToUpper(); 
     else if(fmt == "nospace") 
      return arg.ToString().Replace(" ", ""); 
     // Use this if you want to handle default formatting also 
     else if (arg is IFormattable) 
      return ((IFormattable)arg).ToString(fmt, CultureInfo.CurrentCulture); 
     return arg.ToString(); 
    } 
} 

然後使用它像:

string.Format(new MyFormatter(), 
      "{0:lcase}, {0:ucase}, {0:nospace}", 
      "My Test String") 

這應返回:

我的測試字符串,我的測試STRING ,MyTestString

+0

Shouldn'你是否在'IFormattable''ToString'中傳遞'formatProvider'?你不應該檢查'arg'是否是'IFormattable',然後執行額外的自定義格式? – juharr

+0

@juharr否這兩個問題:在這個例子中傳遞的'formatProvider'是我們的同一個對象,所以它會無限循環:我們傳遞一個默認的格式化程序('CurrentCulture')來處理默認的格式。 'IFormattable'這個事實與'object'的不同之處在於,我們實際上可以將'IFormatProvider'傳遞給'ToString()',所以如果我們在其餘的'ToString()'調用中沒有這樣做,那麼就沒有需要它是'IFormattable'。我們可以擴展這個'ICustomFormatter'來接受一個「鏈接的」'IFormatProvider',然後我們會像你說的那樣做,但在這種情況下,這是沒有必要的。 – Jcl

+0

@juharr當然,這是一個非常簡單的實現只是爲了回答這個問題:-) – Jcl