跟小靜讀CLR via C#(10)-參數

來源:互聯網
上載者:User

 

最近幾天學了參數,其實對於參數本不陌生,從上學學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方式其實會造成一些效能損失,例如在堆上為數組分配記憶體、數組初始化等,所以盡量不要過多使用變長參數。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.