最近幾天學了參數,其實對於參數本不陌生,從上學學C語言基礎的時候就學過了。不過細心學下來,還是收穫了一些。
一、 具名引數、選擇性參數
具名引數和選擇性參數是在Visual C#2010中引入的新特性。 笨地兒我個瓜不兮兮的,今天才知道。
- 選擇性參數:定義方法時為參數設定預設值,調用該方法時可以省略為某些形參指定實參。
- 具名引數:調用方法時,通過指定參數名稱的方式為特定形參指定實參。指定時是根據名稱將形參和實參關聯,而不是與參數在列表中的位置關聯。
例如:
class Program
{
static void Main(string[] args)
{
//選擇性參數
Employee.DisplayInfo(24, "程式員"); //相當於 Employee.DisplayInfo(24, "程式員", 0, "未知",default(datetime));
Employee.DisplayInfo(25, "英語相關", 9500); //相當於 Employee.DisplayInfo(25, "英語相關", 9500,"未知",default(datetime));
//具名引數
//相當於Employee.DisplayInfo(30, "進階軟體工程師", 20000, "Yathur",DateTime.Now);
Employee.DisplayInfo(30, Job: "進階軟體工程師", Salary: 20000, Name: "Yathur", dt: DateTime.Now);
Employee.DisplayInfo(Age: 25, Job: "教師");
Console.Read();
}
}
public class Employee
{
public static void DisplayInfo(int Age, string Job, int Salary = default(int), string Name = "未知", DateTime dt = default(DateTime))
{
Console.WriteLine("姓名:" + Name + ", 年齡:" + Age + ", 職位:" + Job + ", 月薪" + Salary + " " + dt);
}
}運行結果:
在智能感知中,選擇性參數為方括弧標識。
有了具名引數,調用時可以方便地按照形參名稱進行,我們不需要記住或尋找形參在所調用方法的形參列表中的順序。 有了選擇性參數,當面對包含大量參數的方法時,如果含有預設值,我們可以只給有意義的參數指定實參,用起來方便了很多。
使用規則:
Employee.DisplayInfo( Age:25,Job:"教師");
- 具名引數可以調換順序,但是得保證有預設值的參數必須放在無預設值的參數之後,否則會產生編譯錯誤。
注意:如果參數中存在數組參數,這個規則不成立。因為數組參數沒有預設值,也要放到參數列表的最後。
- 預設值必須是編譯時間就能確定的值。例如基元類型、枚舉類型、能設為Null的參考型別等。經常將預設值設定為相應的零值,可以使用關鍵字default、new來實現。
- 含有ref或Out關鍵字的參數不能設定預設值,會產生編譯錯誤。因為這些參數不好設定有意義的預設值
二、 引用方式傳參—Out, Ref
CLR假定方法的參數是以傳值方式進行的,但它允許以傳引用的方式傳遞參數。C#通過Out和ref關鍵字可以傳遞指向執行個體的一個指標,而不是參數本身的值。
Out和Ref的使用區別:
- Out: 在調用之前不必初始化參數值; 被調用的方法內部不能讀取參數值; 返回之前必須為該參數賦值。
- Ref: 調用之前必須初始化參數值; 被呼叫者法可以讀取或者寫入參數的值; 返回之前可以不為該參數賦值(不考慮程式實際意義)。
1.
實值型別使用Out
和Ref
運行結果:
相應的IL中繼資料:
2.
參考型別使用out
和ref
當調用方法時,如果形參類型為實參類型的基類,一般會發生隱式轉換。例如:
public static void Swap(object a, object b)
{
object t = a;
a = b;
b = t;
}
string a = "AAA", b = "BBB";
Swap(a, b);
Console.WriteLine("a=" + a + " b=" + b);
但是運行結果並非我們所願,因為方法預設是以傳值方式傳遞參數的,調用後原來的值是不會改變的。
當以傳引用的方式向方法傳遞參數時,必須保證變數類型與方法簽名中類型一致,而不能自動進行隱式轉換,否則會產生編譯錯誤。例如:
public static void Swap(ref object a, ref object b)
{
object t = a;
a = b;
b = t;
}
為了實現想要的效果,我們可以採用泛型。
public static void Swap<T>(ref T a, ref T b)
{
T t = a;
a = b;
b = t;
}
static void Main(string[] args)
{
string a = "AAA", b = "BBB";
Swap(ref a, ref b);
Console.WriteLine("a=" + a + " b=" + b);
Console.Read();
}
3.
重載
在C#中,可以使用Out或者ref關鍵字進行方法重載,例如下面的例子是合法的:
但是如果兩個方法名稱和參數相同,僅通過out和ref關鍵字是不能算作重載的。
三、 可變數量參數傳遞—Params
某些時候,我們希望方法參數的個數是可變的,Params幫我們實現了這個想法。
執行個體
假如不使用Params關鍵字,我們需要使用第①種調用方式。當添加Params關鍵字後,我們可以採用②③,調用方式看上去更加直觀了。實現了傳遞可變數量參數的效果。
注意事項:
- Params關鍵字參數只能放在參數列表的最後,如果調換上面例子中兩個參數位置,會產生編譯錯誤。
- Params關鍵字只能標識任意類型的一個一維數組。
- Params參數允許為Null值或者長度為0的數組。例如上面例子中的④⑤。
- Params方式其實會造成一些效能損失,例如在堆上為數組分配記憶體、數組初始化等,所以盡量不要過多使用變長參數。