最近有很多地方都用到了方法的默認參數,遂總結之。
(一)先從原理說起
在C#中,一旦為某個參數分配了一個默認值,編譯器就會向內部該參數應用定制一個attribute 即是(OptionalAttribute)這個attribute會在最終生產的文件的元數據類型持久性的存儲下來,除此之外,編譯器會向參數應用一個DefaultParameterValueAttribue,也會將這個特性持久性存儲在最終文件的元數據里面。一旦編譯器發現某個方法調用的時候,缺失部分實參,就可以確定是可選實參並從元數據中提取默認值,將值自動嵌入。說到底還是特性的作用呀,這里有一篇關於特性的文章(https://www.cnblogs.com/gdouzz/p/9684720.html);
有種情況可以適用方法的默認參數的情況,就是別人寫的方法(已經很多地方用了,你現在想加個參數,又不用去改原來引用的代碼)。當然你可以寫個方法的重載,我也曾經想寫重裝來加上這個參數條件。因為重載已經會用了,所以就學習了下方法參數缺省的情況。
下面我給大家提供一個例子,大家可以好好看看,自己動手一試。
SayHello方法的定義如下,當我們寫這個的時候,會怎么進行調用呢,請大家談談。 SayHello("name',"value")
void SayHello(string name, string value, string text = "zz") { Console.WriteLine("走了一個缺省"); } void SayHello(string name, string value, string text = "zz", string age = "test") { Console.WriteLine("走了兩個缺省"); }
我也看了園子里面大內老A寫的那篇文章,講得很好。但是我他說的那些,可以作為入門,但是並不能當成准則來對待。
上面這種寫法並沒有啥毛病,但是如果方法是從模塊的外部調用,更改參數的默認值具有潛在的危險性,call site在調用的嵌入了默認值,如果你以后更改了參數的默認值,但沒有重新編譯call site里面的所在代碼,它在調用你方法的時候,依然會傳遞舊的默認值,所以可以考慮將0/null 作為哨兵的值使用,從而指出默認行為,這樣一來,即使更改了默認值,也不必要重新編譯包含了call site的全部代碼。
//第一種做法
static void TestMethod(string foo,string bar="bar123") {
Console.WriteLine($"{foo}{bar}");
}
//第二種做法
static void TestDefaultMethod(string foo,string bar = null) {
bar = bar ?? "bar123";
Console.WriteLine($"{foo}{bar}");
}
推薦使用下面這種做法
上面這個是最重要的,如果你想着啥時候用缺省參數和函數重載,請根據情況來定吧 。
