欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2015年06月17日 09:21:30   投稿:junjie  
這篇文章主要介紹了C#中的ICustomFormatter及IFormatProvider接口用法揭秘,本文能過分析一段代碼得出一些研究結(jié)果,需要的朋友可以參考下

最近在學(xué)習(xí)IFormatProvider接口的用法時(shí),在網(wǎng)絡(luò)上找了段實(shí)例代碼(具體哪個(gè)網(wǎng)站不記得了,就不給出鏈接了),通過研究實(shí)例代碼,初步了解了IFormatProvider接口的用法。

在學(xué)習(xí)代碼之前,我們先來了解一下本例中使用到的兩個(gè)接口ICustomFormatter及IFormatProvider。

查看MSDN,得到以下關(guān)于ICustomFormatter及IFormatProvider接口的說明。

接口ICustomFormatter:定義一種方法,它支持自定義設(shè)置對象的值的格式。 ICustomFormatter 接口包含單個(gè)方法:ICustomFormatter.Format。當(dāng)此接口由引用或值類型實(shí)現(xiàn)時(shí),F(xiàn)ormat 方法會返回對象值的自定義格式字符串表示形式。

接口IFormatProvider:提供用于檢索控制格式化的對象的機(jī)制。 類或數(shù)值類型實(shí)現(xiàn)此接口的 GetFormat方法,以獲得提供格式信息或?qū)崿F(xiàn)類型的處理的對象。IFormatProvider接口同樣只包含一個(gè)方法。

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

不過,別急,繼續(xù)往下看。

下面給出詳細(xì)代碼,看下面...

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(暫且叫作“自定義格式化類”),該類實(shí)現(xiàn)了ICustomFormatter及IFormatProvider接口,所以該類實(shí)現(xiàn)了 GetFormat及Format方法,其實(shí)該類除了實(shí)現(xiàn)這兩個(gè)方法外,也沒有完成其他任何工作。

GetFormat方法對傳入?yún)?shù)(類型format)進(jìn)行判斷,如果傳入的類型format為ICustomFormatter,就返回類本身,否則返回null。我個(gè)人的理解就是:調(diào)用MyFormater類的GetFormat方法時(shí),傳入類型要求,告訴類MyFormater,你必須滿足類型要求,否則我就不要你了,你要是滿足條件,我就要定你了。從MyFormater的角度來思考的話,就是:我(MyFormater)就能提供類型為ICustomFormatter的我。舉個(gè)不恰當(dāng)?shù)睦樱惴堑靡獋€(gè)人妖,我怎么能給你呢,我可是絕對的純爺們,呵呵大哭??梢?,GetFormat方法主要提供一個(gè)滿足指定要求的對象,該對象提供格式信息。那該對象提供的格式信息由誰來提供呢,當(dāng)然是Format方法,msdn對這個(gè)有很明確的說明,“Format 方法會返回對象值的自定義格式字符串表示形式。”

學(xué)習(xí)到這里,是不是感覺自己有一丁點(diǎn)的明白了呢。

如果還是一團(tuán)漿糊,也沒事,接著往下看。

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

好了,不羅嗦了,繼續(xù)往下看。

在解釋Format方法的具體實(shí)現(xiàn)前,先來看看我們的代碼到底是怎樣運(yùn)行的。

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

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

代碼中采用上面三種方式來調(diào)用string.Format方法,三者的區(qū)別僅在第二個(gè)參數(shù)。要想弄清楚三者的區(qū)別,只有搞清楚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);
}

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

查看string.Format方法體,可以了解到:方法先對傳入?yún)?shù)format及args進(jìn)行非法判斷,參數(shù)為空時(shí)拋出參數(shù)空異常。參數(shù)正常時(shí),初始化StringBuilder 對象(關(guān)于StringBuilderCache.Acquire的使用這里不做過多介紹,自己去研究),接著調(diào)用sb.AppendFormat方法,最后通過語句return StringBuilderCache.GetStringAndRelease(sb)返回結(jié)果??梢姡嬲母袷交僮鞫荚趕b.AppendFormat方法中完成,這里并不打算給出sb.AppendFormat方法的完整代碼,只是給出sb.AppendFormat方法中調(diào)用GetFormat 方法和Format 方法的代碼。

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

代碼傳入?yún)?shù)typeof(ICustomFormatter),返回ICustomFormatter類型的formatter 。

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

上面就是代碼中調(diào)用Format方法的地方。

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

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

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

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

就到這里了。最后給出程序執(zhí)行結(jié)果??聪旅?..

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

相關(guān)文章

最新評論