C# 關於方法中的參數(可選參數和命名參數)


    在閱讀《CLR via C#(第三版)》第191頁中看到方法參數的用法,這里將書本中的內容挑選一些關鍵的記錄下來,內容如下:

 

    設計一個方法的參數時,可為部分或全部參數分配默認值。然后,調用這些方法的代碼可以選擇不指定部分實參,接受其默認值。除此之外,調用方法時,還可通過指定參數名稱的方式為其傳遞實參。以下代碼演示了可選參數和命名參數的用法:

 

using System;
using System.Collections.Generic;
using System.Text;

namespace ParameterInMethod
{
    class Program
    {
        private static int s_n = 0;
        private static void M(int x = 9, string s = "A", DateTime dt = default(DateTime), Guid guid = new Guid())
        {
            Console.WriteLine("x={0},s={1},dt={2},guid={3}",x,s,dt,guid);
        }

        static void Main(string[] args)
        {
            // 1. 等同於M(9, "A", default(DateTime), new Guid());
            M();

            // 2. 等同於M(8, "X", default(DateTime), new Guid());
            M(8, "X");

            // 3. 等同於M(5, "A", DateTime.Now, new Guid());
            M(5, guid: Guid.NewGuid(), dt: DateTime.Now);

            // 4. 等同於M(0, "1", default(DateTime), new Guid());
            M(s_n++, s_n++.ToString());

            // 5. 等同於以下兩行代碼:
            // string t1 = "2"; int t2 = 3;
            // M(t2, t1, default(DateTime), new Guid());
            M(s: (s_n++).ToString(), x: s_n++);


            Console.ReadLine();

            //程序輸出結果如下:
            /*
             * x=9,s=A,dt=0001/1/1 0:00:00,guid=00000000-0000-0000-0000-000000000000
             * x=8,s=X,dt=0001/1/1 0:00:00,guid=00000000-0000-0000-0000-000000000000
             * x=5,s=A,dt=2012/5/31 10:34:28,guid=cdc348c3-6435-40ed-8e37-23d90f4f05ce
             * x=0,s=1,dt=0001/1/1 0:00:00,guid=00000000-0000-0000-0000-000000000000
             * x=3,s=2,dt=0001/1/1 0:00:00,guid=00000000-0000-0000-0000-000000000000
             */

        }
    }
}

 

如你所見,如果調用時省略了一個實參,C#編譯器會自動嵌入參數的默認值。

在對 M 的第4個調用中 s_n 中的當前值(0)傳給x,然后 s_n 遞增。隨后, s_n 的當前值(1)作為一個字符串傳給 s, 然后繼續遞增到 2. 使用已命名的參數傳遞實參時,編譯器仍然按從左到右的順序對實參進行求值。

在對 M 的第5個調用中, s_n 中的當前值(2)被轉換成一個字符串,並保存到編譯器創建的一個臨時變量(t1)中。接着, s_n 遞增到3,這個值保存到編譯器創建另一個臨時變量(t2)中。然后, s_n 繼續遞增到4. 最后調用M時,向它傳遞的實參一次是 t2,t1 一個默認DateTime 和 新建的guid。

 

規則和原則:

  • 可以為方法、構構造器方法和有參屬性(C#索引器)的參數指定默認值。還可為屬於委托定義一部分的參數指定默認值。然后,在調用該委托類型的一個變量時,可以省略實參,以接受默認值。
  • 有默認值的參數必須在沒有默認值的所有參數之后。換言之,一旦定義了一個有默認值的參數,它右邊的所有參數也必須有默認值。例如在面前的 M 方法定義中,如果刪除 s 的默認值(“A”),就會出現編譯錯誤。但這個規則有一個例外:“參數數組”這種參數必須放在所有參數(包括有默認值的這些)之后,而且數組本身不能有一個默認值。
  • 默認值必須是編譯時能確定的常量值。那么,能為哪些參數設置默認值呢?這些參數的類型可以是C#認定的基元類型。還可以包括枚舉類型,以及能設為 null 的任何引用類型。對於任何值類型的一個參數,可將默認值設為值類型的一個實例,並讓它的所有字段都包含零值。可以用 default 關鍵字或者 new 關鍵字來表達這個意思;兩種語法將生成完全一致的IL代碼。在 M 方法中設置 dt 參數和 guid 參數的默認值時,分別使用的就是這兩種語法。
  • 注意不要重命名參數變量。否則,任何調用者如果以傳參數名的方式傳遞參數,都必須修改它們的代碼。例如,在前面的 M 方法聲明中,如果將dt變量重命名為 dateTime,對 M 的第三個調用就會造成編譯錯誤:error CS1739:"M" 的最佳重載沒有名為“dt”的參數。
  • 如果參數用 ref 或 out 關鍵字進行了標識,就不能設置默認值。因為沒有辦法為這些參數傳遞一個有意義的默認值。
  • C#不允許省略逗號之間實參,比如M(1, , DateTime.Now).因為會造成可讀性的影響,程序員將被迫去數這些逗號。

 

大概就是以上內容,具體細節的這里並沒有說的特別的全面,可以參考本文的前面說的書籍作為參考。

 

我測試的一個Demo源碼下載:http://files.cnblogs.com/andrew-blog/ParameterInMethod.rar

參考:http://www.wxzzz.com/?id=100


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM