国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

C#中的ICustomFormatter及IFormatProvider接口用法揭秘

2020-01-24 01:42:50
字體:
來源:轉載
供稿:網友

最近在學習IFormatProvider接口的用法時,在網絡上找了段實例代碼(具體哪個網站不記得了,就不給出鏈接了),通過研究實例代碼,初步了解了IFormatProvider接口的用法。

在學習代碼之前,我們先來了解一下本例中使用到的兩個接口ICustomFormatter及IFormatProvider。

查看MSDN,得到以下關于ICustomFormatter及IFormatProvider接口的說明。

接口ICustomFormatter:定義一種方法,它支持自定義設置對象的值的格式。 ICustomFormatter 接口包含單個方法:ICustomFormatter.Format。當此接口由引用或值類型實現時,Format 方法會返回對象值的自定義格式字符串表示形式。

接口IFormatProvider:提供用于檢索控制格式化的對象的機制。 類或數值類型實現此接口的 GetFormat方法,以獲得提供格式信息或實現類型的處理的對象。IFormatProvider接口同樣只包含一個方法。

可能單純閱讀MSDN的說明,還是有點一知半解的感覺。

不過,別急,繼續往下看。

下面給出詳細代碼,看下面...

public class MyFormater:ICustomFormatter,IFormatProvider{  public object GetFormat(Type format)  {    if (format == typeof(ICustomFormatter))      return this;    return null;  }  public string Format(string format, object arg, IFormatProvider provider)  {    if (format == null)    {      if (arg is IFormattable)       return ((IFormattable)arg).ToString(format, provider);      return arg.ToString();    }    else    {      if (format == "MyFormater")      {        return "**" + arg.ToString();      }      else      {        if (arg is IFormattable)          return ((IFormattable)arg).ToString(format, provider);        return arg.ToString();      }    }  }}static void Main(string[] args){      int i = 100;   string printString;   MyFormater myFormater = new MyFormater();   printString = string.Format(myFormater, "{0}", i);   Console.WriteLine("{0}", printString);   printString = string.Format(myFormater, "{0:C}", i);   Console.WriteLine("{0}", printString);   printString = string.Format(myFormater, "{0:MyFormater}", i);   Console.WriteLine("{0}", printString);}

代碼中定義了類MyFormater(暫且叫作“自定義格式化類”),該類實現了ICustomFormatter及IFormatProvider接口,所以該類實現了 GetFormat及Format方法,其實該類除了實現這兩個方法外,也沒有完成其他任何工作。

GetFormat方法對傳入參數(類型format)進行判斷,如果傳入的類型format為ICustomFormatter,就返回類本身,否則返回null。我個人的理解就是:調用MyFormater類的GetFormat方法時,傳入類型要求,告訴類MyFormater,你必須滿足類型要求,否則我就不要你了,你要是滿足條件,我就要定你了。從MyFormater的角度來思考的話,就是:我(MyFormater)就能提供類型為ICustomFormatter的我。舉個不恰當的例子,你非得要個人妖,我怎么能給你呢,我可是絕對的純爺們,呵呵大哭。可見,GetFormat方法主要提供一個滿足指定要求的對象,該對象提供格式信息。那該對象提供的格式信息由誰來提供呢,當然是Format方法,msdn對這個有很明確的說明,“Format 方法會返回對象值的自定義格式字符串表示形式。”

學習到這里,是不是感覺自己有一丁點的明白了呢。

如果還是一團漿糊,也沒事,接著往下看。

不過,到這里,不管你腦子里到底有多漿糊。我都希望你至少能明白一點,那就是GetFormat方法負責返回提供格式信息的對象(這里的MyFormater),而Format 方法負責返回具體的格式信息。說得再簡單點,那就是:先得到提供格式化信息的對象,再得到該對象提供的格式化信息。

好了,不羅嗦了,繼續往下看。

在解釋Format方法的具體實現前,先來看看我們的代碼到底是怎樣運行的。

在Main函數中,定義整型變量i,并初始化為100;定義字符串printString用來保存返回值;實例化MyFormater,得到對象myFormater。并調用string.Format方法生成printString。

printString = string.Format(myFormater, "{0}", i);printString = string.Format(myFormater, "{0:C}", i);printString = string.Format(myFormater, "{0:MyFormater}", i);

代碼中采用上面三種方式來調用string.Format方法,三者的區別僅在第二個參數。要想弄清楚三者的區別,只有搞清楚string.Format方法到底做了些什么才能知道,所以下面來看看string.Format方法都做了些什么。

在這里,我們需要使用Reflector來查看string.Format方法的源碼。

string.Format方法的代碼如下:

public static string Format(IFormatProvider provider, string format, params object[] args){  if ((format == null) || (args == null))  {    throw new ArgumentNullException((format == null) ? "format" : "args");  }  StringBuilder sb = StringBuilderCache.Acquire(format.Length + (args.Length * 8));  sb.AppendFormat(provider, format, args);  return StringBuilderCache.GetStringAndRelease(sb);}

結合我們的函數調用閱讀函數簽名,了解到:string.Format方法的第一個參數接收我們傳入的自定義格式化類對象myFormater,第二個參數接收格式化字符串format,第三個參數接收需要被格式化的參數集合args,這里僅變量i。

查看string.Format方法體,可以了解到:方法先對傳入參數format及args進行非法判斷,參數為空時拋出參數空異常。參數正常時,初始化StringBuilder 對象(關于StringBuilderCache.Acquire的使用這里不做過多介紹,自己去研究),接著調用sb.AppendFormat方法,最后通過語句return StringBuilderCache.GetStringAndRelease(sb)返回結果。可見,真正的格式化操作都在sb.AppendFormat方法中完成,這里并不打算給出sb.AppendFormat方法的完整代碼,只是給出sb.AppendFormat方法中調用GetFormat 方法和Format 方法的代碼。

if (provider != null){    formatter = (ICustomFormatter) provider.GetFormat(typeof(ICustomFormatter)); }

代碼傳入參數typeof(ICustomFormatter),返回ICustomFormatter類型的formatter 。

if (formatter != null){  if (builder != null)  {    str = builder.ToString();      }  str2 = formatter.Format(str, arg, provider);}

上面就是代碼中調用Format方法的地方。

執行上面代碼都會去執行我們的自定義格式化類MyFormater的代碼。

要想了解詳細的執行情況,那就請代開你的VS,開始敲代碼吧。

好像到這里,我也沒有把問題很好的解釋清楚。

這與我對.NET庫代碼一竅不通是有很大關系的。其實,到這里,我對sb.AppendFormat方法的具體操作也還是停留在了解的層面上,所以就沒有過多敘述了。希望大家能諒解。但是到最后,大家至少對我們自定義的格式化類MyFormater在.NET庫中是如何被使用的應該有一個初步認識了。

就到這里了。最后給出程序執行結果。看下面...

哦,忘了解釋Format方法的代碼,哎,太累了,就不解釋了,大家都是牛人,能看懂的。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 安平县| 石门县| 葵青区| 彭水| 乌恰县| 双柏县| 昌宁县| 上栗县| 杂多县| 岳西县| 宁强县| 顺平县| 抚州市| 襄城县| 赫章县| 左贡县| 林周县| 城口县| 杂多县| 江都市| 花莲市| 吴忠市| 克什克腾旗| 射洪县| 富川| 宜昌市| 清徐县| 贵定县| 新乐市| 河津市| 利津县| 平乐县| 永靖县| 怀来县| 灌云县| 三门峡市| 利辛县| 大田县| 威宁| 华亭县| 闵行区|