關(guān)于C# 4.0新特性“缺省參數(shù)”的實(shí)現(xiàn)詳解
前言
C#4.0關(guān)于缺省參數(shù)的新特性,相信大家都不會(huì)陌生。所謂缺省參數(shù),顧名思義,就是在聲明方法的某個(gè)參數(shù)的時(shí)候?yàn)橹付ㄒ粋€(gè)默認(rèn)值,在調(diào)用該方法的時(shí)候如果采用該默認(rèn)值,你就無(wú)須指定該參數(shù)。和很多語(yǔ)言層面特性(語(yǔ)法糖)的實(shí)現(xiàn)一樣,缺省參數(shù)也是編譯器為我們玩的一個(gè)小花招。缺省參數(shù)最終體現(xiàn)為兩個(gè)特殊的自定義特性O(shè)ptionalAttribute和DefaultParameterValueAttribute 。
目錄
- 一、缺省參數(shù)的用法
- 二、實(shí)現(xiàn)缺省參數(shù)的兩個(gè)特性:OptionalAttribute和DefaultParameterValueAttribute
- 三、直接通過(guò)OptionalAttribute和DefaultParameterValueAttribute 定義缺省參數(shù)
一、缺省參數(shù)的用法
比如下面一個(gè)TestMethod方法,后面兩個(gè)參數(shù)bar和baz就是缺省參數(shù),默認(rèn)值分別為“Bar”和“Baz”。
1: static void TestMethod(string foo, string bar = "Bar", string baz = "Baz")
2: {
3: Console.WriteLine("{0, -5} - {1, -5} - {2, -5}", foo, bar, baz);
4: }
在調(diào)用TestMethod的時(shí)候,我們自由地選擇采用缺省的參數(shù)值,或者覆蓋該缺省值。
1: static void Main(string[] args)
2: {
3: TestMethod("Foo");
4: TestMethod("Foo", "Bar1");
5: TestMethod("Foo", "Bar1", "Baz1");
6: }
下面是輸出結(jié)果:
1: Foo - Bar - Baz
2: Foo - Bar1 - Baz
3: Foo - Bar1 - Baz1
缺省參數(shù)的使用有兩個(gè)簡(jiǎn)單的限制,其一是:缺省參數(shù)的聲明只能放在普通參數(shù)之后。如下代碼中定義的TestMethod方法中,缺省參數(shù)bar后面跟一個(gè)非缺省參數(shù)baz,這樣的代碼是不能通過(guò)編譯的(編譯錯(cuò)誤信息為:Optional parameters must appear after all required parameters)。
1: static void TestMethod(string foo, string bar = "Bar", string baz)
2: {
3: Console.WriteLine("{0, -5} - {1, -5} - {2, -5}", foo, bar, baz);
4: }
但是,缺省參數(shù)后面可以跟數(shù)組參數(shù)(params參數(shù)),實(shí)際上無(wú)論在什么情況下,params參數(shù)都只能是最后一個(gè)聲明的參數(shù)。關(guān)于缺省參數(shù)的聲明的位置限制,主要重載方法的識(shí)別機(jī)制決定的,這一點(diǎn)大家都很容易理解。
缺省參數(shù)的另一個(gè)限制是:指定的缺省值必須是一個(gè)常量,這就實(shí)際上為作為缺省參數(shù)的數(shù)據(jù)類型作了限制——只能是系統(tǒng)定義的基元類型。下面定義的TestMethod方法中,我們定義了一個(gè)DateTime類型的缺省參數(shù),并將參數(shù)缺省值作為DateTime.Now。由于DateTime.Now不是常量,所以這樣的代碼也不能通過(guò)編譯(編譯錯(cuò)誤消息:Default parameter value for 'date' must be a compile-time constant)。
1: static void TestMethod(DateTime date = DateTime.Now)
2: {
3: //Others...
4: }
二、實(shí)現(xiàn)缺省參數(shù)的兩個(gè)特性:OptionalAttribute和DefaultParameterValueAttribute
為什么缺省參數(shù)的默認(rèn)值只能接受常量呢?如果你了解了缺省參數(shù)的本質(zhì),這就不是一個(gè)問(wèn)題。那么缺省參數(shù)究竟是如何實(shí)現(xiàn)的呢?
和很多語(yǔ)言層面特性(語(yǔ)法糖)的實(shí)現(xiàn)一樣,缺省參數(shù)也是編譯器為我們玩的一個(gè)小花招,而真正編譯后的東西都是我們?cè)偈煜げ贿^(guò)的玩意兒。當(dāng)包含缺省參數(shù)的C#代碼經(jīng)過(guò)編譯后,缺省參數(shù)體現(xiàn)在兩個(gè)特殊的自定義特性O(shè)ptionalAttribute和DefaultParameterValueAttribute 。前者將參數(shù)標(biāo)識(shí)為缺省參數(shù),后者指定其缺省值。
1: [ComVisible(true), AttributeUsage(AttributeTargets.Parameter, Inherited=false)]
2: public sealed class OptionalAttribute : Attribute
3: {
4: }
5:
6: [AttributeUsage(AttributeTargets.Parameter)]
7: public sealed class DefaultParameterValueAttribute : Attribute
8: {
9: public DefaultParameterValueAttribute(object value);
10: public object Value {get; }
11: }
對(duì)于最開(kāi)始我們定義的TestMethod方法,編譯后的形式如下所示。
1: private static void TestMethod(string foo,
2: [Optional, DefaultParameterValue("Bar")] string bar,
3: [Optional, DefaultParameterValue("Baz")] string baz)
4: {
5: //Others..
6: }
正是因?yàn)槿笔?shù)的默認(rèn)值最終是作為DefaultParameterValueAttribute的參數(shù)存在的,所以它必須是常量。
三、直接通過(guò)OptionalAttribute和DefaultParameterValueAttribute 定義缺省參數(shù)
既然缺省參數(shù)最終體現(xiàn)為OptionalAttribute和DefaultParameterValueAttribute 這兩個(gè)特性,我們是否可以直接通過(guò)它們來(lái)定義缺省參數(shù)呢?答案是:當(dāng)然可以,下面的代碼一樣可以正常執(zhí)行。
1: static void Main(string[] args)
2: {
3: TestMethod("Foo");
4: TestMethod("Foo","Bar1");
5: TestMethod("Foo","Bar1","Baz1");
6: }
7:
8: private static void TestMethod(string foo,
9: [Optional, DefaultParameterValue("Bar")] string bar,
10: [Optional, DefaultParameterValue("Baz")] string baz)
11: {
12: //Others..
13: }
如果調(diào)用含有缺省參數(shù)的方法,并且沒(méi)有顯示指定該參數(shù),編譯器在編譯的時(shí)候會(huì)自動(dòng)將默認(rèn)值附加上去。對(duì)于上面的Main方法,下面是與之等效的編譯后代碼。
1: private static void Main(string[] args)
2: {
3: TestMethod("Foo", "Bar", "Baz");
4: TestMethod("Foo", "Bar1", "Baz");
5: TestMethod("Foo", "Bar1", "Baz1");
6: }
雖然說(shuō)我們通過(guò)OptionalAttribute和DefaultParameterValueAttribute 這兩個(gè)特性也可以定義缺省參數(shù),但是當(dāng)我們將缺省參數(shù)定義在普通參數(shù)之前是,編譯器不會(huì)報(bào)錯(cuò)。倒是方法中缺省參數(shù)實(shí)際上就相當(dāng)于普通參數(shù)了。
1: static void Main(string[] args)
2: {
3: //TestMethod("Foo","Baz");
4: //上面的方法調(diào)用無(wú)效
5: TestMethod("Foo","Bar1","Baz1");
6: }
7: private static void TestMethod(string foo,
8: [Optional, DefaultParameterValue("Bar")] string bar,
9: string baz)
10: {
11: //Others..
12: }
總結(jié)
到此這篇關(guān)于C# 4.0新特性“缺省參數(shù)”的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)C#4.0新特性“缺省參數(shù)”內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#抓取網(wǎng)絡(luò)圖片保存到本地的實(shí)現(xiàn)方法
下面小編就為大家分享一篇C#抓取網(wǎng)絡(luò)圖片保存到本地的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01
C#實(shí)現(xiàn)根據(jù)字節(jié)數(shù)截取字符串并加上省略號(hào)的方法
這篇文章主要介紹了C#實(shí)現(xiàn)根據(jù)字節(jié)數(shù)截取字符串并加上省略號(hào)的方法,比較實(shí)用的功能,需要的朋友可以參考下2014-07-07
C#使用Object類實(shí)現(xiàn)棧的方法詳解
這篇文章主要介紹了C#使用Object類實(shí)現(xiàn)棧的方法,詳細(xì)分析了棧的原理及使用Object類實(shí)現(xiàn)棧的相關(guān)技巧與注意事項(xiàng),需要的朋友可以參考下2016-06-06
C#使用iTextSharp將PDF轉(zhuǎn)成文本的方法
這篇文章主要介紹了C#使用iTextSharp將PDF轉(zhuǎn)成文本的方法,涉及C#操作pdf文件的相關(guān)技巧,需要的朋友可以參考下2015-05-05
C#實(shí)現(xiàn)手機(jī)拍照并且保存水印照片
這篇文章主要介紹了C#實(shí)現(xiàn)手機(jī)拍照并且保存水印照片的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11
C# 設(shè)置防火墻的創(chuàng)建規(guī)則
這篇文章主要介紹了C# 設(shè)置防火墻的創(chuàng)建規(guī)則,幫助大家更好的利用c#操作防火墻,感興趣的朋友可以了解下2020-11-11
使用C#與SQL Server數(shù)據(jù)庫(kù)進(jìn)行交互的詳細(xì)步驟
在C#中與數(shù)據(jù)庫(kù)進(jìn)行交互,通常使用ADO.NET(ActiveX Data Objects .NET)框架,ADO.NET是.NET Framework中用于數(shù)據(jù)訪問(wèn)的一組類庫(kù),它提供了多種用于連接和操作數(shù)據(jù)庫(kù)的方法,以下是使用C#與SQL Server數(shù)據(jù)庫(kù)進(jìn)行交互的詳細(xì)步驟,需要的朋友可以參考下2024-08-08

