C#中的ICustomFormatter及IFormatProvider接口用法揭秘。本站提示廣大學習愛好者:(C#中的ICustomFormatter及IFormatProvider接口用法揭秘)文章只能為提供參考,不一定能成為您想要的結果。以下是C#中的ICustomFormatter及IFormatProvider接口用法揭秘正文
比來在進修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辦法的代碼,哎,太累了,就不說明了,年夜家都是牛人,能看懂的。