C#系列文章之参数
解決的主要問題:
文章的主要內容:
- 可選參數和命名參數
- 隱式類型的局部變量
- 以傳引用的方式向方法傳遞參數
- 向方法傳遞可變數量的參數
- 參數和返回類型的設計規范
- 常量性
1.1可選參數和命名參數
在方法中為部分參數指定默認值的規則和原則:
- 可為方法,構造器方法和有參屬性(C#索引器)的參數,委托定義一部分的參數指定默認值。并且默認值必須是編譯時能確定的常量值,可以是基元類型,枚舉類型以技能設為null的任何引用類型。可以使用default和new來設置默認值
- 不要重命名參數變量(否則調用者在以傳參數名的方式傳遞實參時要修改代碼)。如果方法被模塊的外部進行調用,不要隨意更改默認值,比如下面的例子: ? ? ? ? ? ? ? ? ? ? ? ? ? ? //不要這樣做
private static string MakePath(string filename="Untitled")
{return string.Format(@"C:\{0}.txt",filename);
}
//而要這樣做
private static string MakePath(string filename=null)
{return string.Format(@"C:\{0}.txt",filename??"Untitled");
}
?
- 如果參數用ref或out關鍵字進行標識,則不能設置默認值,因為沒有辦法為這些參數傳遞有意義的默認值。
調用方法時,傳參數時規則和原則:
- 命名參數只能出現在實參列表的尾部
- 所有必須的實參必須都傳遞
- 如果參數要求ref/out,為了以傳遞參數名的方式傳遞實參,要使用下面語法:
?此外不能用var聲明方法的參數類型,不要混淆dynamic和var。用var聲明局部變量只是一種簡化的語法,他要求編譯器根據表達式推斷出具體數據類型,其只能聲明方法內部的局部變量,而dynamic關鍵字適用于局部變量,字段和參數。另外,必須顯示初始化用var聲明的變量。
?
1.2以傳引用的方式向方法傳遞參數(out ref)
? ? ?CLR默認所有方法參數都傳值,對于引用類型,對象的指針被傳給方法,這個指針也是當做值來傳遞的,意味著方法能修改對象。對于值類型,由于是在棧上,傳給方法是一個副本,調用者中的實例不受影響。
? ? ?CLR不區分out和ref,無論用哪個都會生成相同的IL代碼。元數據除了有一個bit用于說明是out還是ref外,剩下幾乎一致。用out標記表明調用者在調用方法之前不指望你已初始化好了對象,被調用的方法不能讀取參數的值,要求返回前必須向這個值寫入。用ref標記,調用者就必須先初始化參數的值。為較大的值類型使用out,可提升代碼執行效率,因為它避免了在進行方法調用時復制值類型實例的字段。
? ? ?CLR允許根據使用的是out 還是ref參數對方法進行重載,例如:
? ? ?
//如下兩個方法可以實現重載, //但是如果只有out和ref區別,則不合法, //因為兩個簽名的元數據形式相同 public class Point {void Add(Point p){.....};void Add(ref Point p){.....}; }?
1.3 向方法傳遞可變數量的參數
? ?使用如下聲明,接受可變數量的參數
??
int Add(params int[] values) {int sum =0;if(values!=null){for(int x = 0; x<values.length;x++){.....}}return sum }調用時可以是Add(new int[]{1,2,3...});也可以是Add(1,2,3...);
? ? ? ? 編譯器在檢測到方法調用時,會檢查所有具有指定名稱同時參數沒有應用ParamArray特性的方法。找到就生成調用它所需的代碼,否則就檢查應用ParamArray特性的方法,此時編譯器生成代碼構造一個數組,填充元素,再生成代碼來調用所選的方法。
? ? ? ? 只有方法最后一個參數才可以用Params關鍵字標記,也只能標識一組數組(任意類型),可傳遞null或不傳值;
? ? ? ? 調用參數數量可變的方法對性能有所影響(除非顯式傳遞null)。畢竟數組對象必須在堆上分配,數組元素必須初始化,而且數組內存最終需要垃圾回收。為此可以定義幾個沒有使用params關鍵字的重載版本。
1.4 參數和返回類型的設計規范
? ? ? ? 聲明方法參數類型應盡量指定最弱類型,寧愿要接口也不要基類。比如處理一組數據項,最好用IEnumerable<T>,而不要用強數據類型List<T>或強接口類型ICollection<T>或IList<T>。原因是要盡可能使接受的參數范圍廣,更靈活。相反一般將方法返回類型聲明為最強類型(防止受限于特定類型)。總之確保調用者調用方法有盡量大的靈活性,使方法適用范圍更大。
? ? ? ? ?有時在不影響調用者前提下修改方法內部實現。如果方法返回List<string>,可能會在未來某個時候修改內部方法實現返回string[]。若想保持一定的靈活性,可以選擇較弱的返回類型。比如IList<string>不建議使用最弱的IEnumerable<string>,也不使用較強的IConllction<string>
?
轉載于:https://www.cnblogs.com/mjys-gh/p/6459477.html
總結
- 上一篇: Linux shell编程学习笔记---
- 下一篇: [C# 设计模式] Iterator -