C#4.0關于預設參數的新特性,相信大家都不會陌生。所謂預設參數,顧名思義,就是在聲明方法的某個參數的時候為之指定一個預設值,在調用該方法的時候如果采用該預設值,你就無須指定該參數。和很多語言層面特性(文法糖)的實作一樣,預設參數也是編譯器為我們玩的一個小花招。預設參數最終展現為兩個特殊的自定義特性OptionalAttribute和DefaultParameterValueAttribute 。
目錄
一、預設參數的用法
二、實作預設參數的兩個特性:OptionalAttribute和DefaultParameterValueAttribute
三、直接通過OptionalAttribute和DefaultParameterValueAttribute 定義預設參數
一、預設參數的用法
比如下面一個TestMethod方法,後面兩個參數bar和baz就是預設參數,預設值分别為“Bar”和“Baz”。
static void TestMethod(string foo, string bar = "Bar", string baz = "Baz")
{
Console.WriteLine("{0, -5} - {1, -5} - {2, -5}", foo, bar, baz);
}
在調用TestMethod的時候,我們自由地選擇采用預設的參數值,或者覆寫該預設值。
static void Main(string[] args)
TestMethod("Foo");
TestMethod("Foo", "Bar1");
TestMethod("Foo", "Bar1", "Baz1");
}
下面是輸出結果:
Foo - Bar - Baz
Foo - Bar1 - Baz
Foo - Bar1 - Baz1
預設參數的使用有兩個簡單的限制,其一是:預設參數的聲明隻能放在普通參數之後。如下代碼中定義的TestMethod方法中,預設參數bar後面跟一個非預設參數baz,這樣的代碼是不能通過編譯的(編譯錯誤資訊為:Optional parameters must appear after all required parameters)。
上海徐彙企業網站設計與制作>
static void TestMethod(string foo, string bar = "Bar", string baz)
}
但是,預設參數後面可以跟數組參數(params參數),實際上無論在什麼情況下,params參數都隻能是最後一個聲明的參數。關于預設參數的聲明的位置限制,主要重載方法的識别機制決定的,這一點大家都很容易了解。
預設參數的另一個限制是:指定的預設值必須是一個常量,這就實際上為作為預設參數的資料類型作了限制——隻能是系統定義的基元類型。下面定義的TestMethod方法中,我們定義了一個DateTime類型的預設參數,并将參數預設值作為DateTime.Now。由于DateTime.Now不是常量,是以這樣的代碼也不能通過編譯(編譯錯誤消息:Default parameter value for 'date' must be a compile-time constant)。
static void TestMethod(DateTime date = DateTime.Now)
//Others...
}
二、實作預設參數的兩個特性:OptionalAttribute和DefaultParameterValueAttribute
為什麼預設參數的預設值隻能接受常量呢?如果你了解了預設參數的本質,這就不是一個問題。那麼預設參數究竟是如何實作的呢?
和很多語言層面特性(文法糖)的實作一樣,預設參數也是編譯器為我們玩的一個小花招,而真正編譯後的東西都是我們再熟悉不過的玩意兒。當包含預設參數的C#代碼經過編譯後,預設參數展現在兩個特殊的自定義特性OptionalAttribute和DefaultParameterValueAttribute 。前者将參數辨別為預設參數,後者指定其預設值。
[ComVisible(true), AttributeUsage(AttributeTargets.Parameter, Inherited=false)]
public sealed class OptionalAttribute : Attribute
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class DefaultParameterValueAttribute : Attribute
public DefaultParameterValueAttribute(object value);
public object Value {get; }
對于最開始我們定義的TestMethod方法,編譯後的形式如下所示。
private static void TestMethod(string foo,
[Optional, DefaultParameterValue("Bar")] string bar,
[Optional, DefaultParameterValue("Baz")] strin上海闵行企業網站設計與制作g baz)
//Others..
正是因為預設參數的預設值最終是作為DefaultParameterValueAttribute的參數存在的,是以它必須是常量。
三、直接通過OptionalAttribute和DefaultParameterValueAttribute 定義預設參數
TestMethod("Foo","Bar1");
TestMethod("Foo","Bar1","Baz1");
[Optional, DefaultParameterValue("Baz")] string baz)
private static void Main(string[] args)
TestMethod("Foo", "Bar", "Baz");
TestMethod("Foo", "Bar1", "Baz");
//TestMethod("Foo","Baz");
//上面的方法調用無效
TestMethod("Foo","Bar1","Baz1上海徐彙企業網站制作style='color:white;' href='http://www.93tj.com'>上海網站建設"color: #800000;">");
string baz)