1. 程式人生 > >C#學習筆記(11)-委託

C#學習筆記(11)-委託

為什麼要使用委託

需要將方法作為一個引數傳遞給另一個方法。
結合委託的概念,可以將以下程式碼:

        static void Main(string[] args)
        {
            //三個需求
            //1.將一個字串陣列中的每個元素都轉換成大寫
            //2.將一個字串陣列中的每個元素都轉換成小寫
            //3.將一個字串陣列中的每個元兩邊都加上雙引號
            string[] names = { "abCDefG", "HIJKlmnOP", "QRsTuvW", "XyX"
}; //ProsToUpper(names); //ProsToLower(names); AddQuot(names); foreach (var item in names) { Console.WriteLine(item); } Console.ReadKey(); } /// <summary> /// 轉成大寫 /// </summary>
/// <param name="name"></param> public static void ProsToUpper(string[] name) { for (int i = 0; i < name.Length; i++) { name[i] = name[i].ToUpper(); } } /// <summary> /// 轉成小寫 /// </summary>
/// <param name="name"></param> public static void ProsToLower(string[] name) { for (int i = 0; i < name.Length; i++) { name[i] = name[i].ToLower(); } } /// <summary> /// 加雙引號 /// </summary> /// <param name="name"></param> public static void AddQuot(string[] name) { for (int i = 0; i < name.Length; i++) { name[i] = "\"" + name[i] + "\""; } }

修改成:

        //在類內部宣告一個委託
        //委託的語法:
        //1、訪問許可權;2、delegate關鍵字;3、返回值型別;4、委託名;5、引數列表
        public delegate string Str(string name);

        static void Main(string[] args)
        { 
            //三個需求
            //1.將一個字串陣列中的每個元素都轉換成大寫
            //2.將一個字串陣列中的每個元素都轉換成小寫            
            //3.將一個字串陣列中的每個元兩邊都加上雙引號
            string[] names = { "abCDefG", "HIJKlmnOP", "QRsTuvW", "XyX" };
            StrPro(names, StrToUpper);
            foreach (var item in names)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();


        }

        public static void StrPro(string[] name,Str del)
        {
            for (int i = 0; i < name.Length; i++)
            {
                name[i] = del(name[i]);
            }
        }

        public static string StrToUpper(string name)
        {
            return name.ToUpper();
        }

        public static string StrToLower(string name)
        {
            return name.ToLower();
        }

        public static string StrAddQuto(string name)
        {
            return "\"" + name + "\"";
        }      

委託概念

函式的簽名必須和委託的簽名一致。
簽名:函式的返回值型別和引數型別,數量

    //宣告一個委託指向一個函式,必須和指向的函式簽名相同
    //簽名是指返回值和傳入的引數
    public delegate void DelSayHi(string name);

    class Program
    {
        static void Main(string[] args)
        {
            DelSayHi del = new DelSayHi(SayHiChinese);
            del("張三");
            Console.ReadKey();
        }

        public static void SayHiChinese(string name)
        {
            Console.WriteLine("吃了嗎?" + name);
        }

        public static void SayHiEnglish(string name)
        {
            Console.WriteLine("Nice to meet you!" + name);
        }

以下程式碼展示了委託如何將函式作為一個引數傳遞給另一個函式的。

//宣告一個委託指向一個函式,必須和指向的函式簽名相同
    //簽名是指返回值和傳入的引數
    public delegate void DelSayHi(string name);

    class Program
    {
        static void Main(string[] args)
        {
            //將函式作為引數傳遞給另一個函式
            Test("Lucy", SayHiEnglish);
            Console.ReadKey();
        }

        public static void Test(string name,DelSayHi del)
        {
            del(name);
        }
        public static void SayHiChinese(string name)
        {
            Console.WriteLine("吃了嗎?" + name);
        }

        public static void SayHiEnglish(string name)
        {
            Console.WriteLine("Nice to meet you!" + name);
        }

匿名函式

當這個方法就執行一次的時候,可以不宣告函式,寫一個匿名函式。
還可以將第一個例子改成匿名函式。
程式碼如下:

        //在類內部宣告一個委託
        //委託的語法:
        //1、訪問許可權;2、delegate關鍵字;3、返回值型別;4、委託名;5、引數列表
        public delegate string Str(string name);

        static void Main(string[] args)
        { 
            //三個需求
            //1.將一個字串陣列中的每個元素都轉換成大寫
            //2.將一個字串陣列中的每個元素都轉換成小寫            
            //3.將一個字串陣列中的每個元兩邊都加上雙引號
            string[] names = { "abCDefG", "HIJKlmnOP", "QRsTuvW", "XyX" };
            //匿名函式
            //語法:1、delegate;2、引數列表;3、方法體。
            StrPro(names, delegate(string name)
            {
                return name.ToUpper();
            });

            foreach (var item in names)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();


        }

        public static void StrPro(string[] name,Str del)
        {
            for (int i = 0; i < name.Length; i++)
            {
                name[i] = del(name[i]);
            }
        }

例子2:

        public delegate void SayHiDel(string name);

        static void Main(string[] args)
        {
            //delegate所宣告的函式相當於是與SayHiDel簽名一致的函式,可以直接賦值給這個委託
            //然後通過宣告的委託呼叫這個函式
            SayHiDel del = delegate (string name)
              {
                  Console.WriteLine("您好!" + name);
              };
            del("張三");
            Console.ReadKey();
        }

泛型委託

求任意陣列中的最大值,用object型別宣告陣列,其實現原始碼如下:

        //宣告一個委託
        public delegate int DelCompare(object o1, object o2);

        static void Main(string[] args)
        {
            //求任意陣列中的最大值
            object[] nums = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            Console.WriteLine(GetMax(nums, Compare));
            Console.ReadKey();


        }

        //比較兩個數大小,將更大值賦值給max
        public static object GetMax(object[] nums,DelCompare del)
        {
            object max = nums[0];
            for (int i = 1; i < nums.Length; i++)
            {
                if(del(max,nums[i])<0)
                {
                    max = nums[i];
                }
            }
            return max;
        }

        //比較兩個數的大小
        public static int Compare(object o1,object o2)
        {
            int n1 = (int)o1;
            int n2 = (int)o2;
            return n1 - n2;
        }
  ```
  泛型委託的寫法為:

    //宣告一個委託
    public delegate int DelCompare<T>(T t1, T t2);

    static void Main(string[] args)
    {
        //求任意陣列中的最大值
        int[] nums = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        Console.WriteLine(GetMax<int>(nums, delegate(int n1,int n2)
        {
            return n1 - n2;
        }));
        Console.ReadKey();              
    }

    //比較兩個數大小,將更大值賦值給max
    public static T GetMax<T>(T[] nums,DelCompare<T> del)
    {
        T max = nums[0];
        for (int i = 1; i < nums.Length; i++)
        {
            if(del(max,nums[i])<0)
            {
                max = nums[i];
            }
        }
        return max;
    }

#lamda表示式

語法1:

    public delegate void DelOne();
    public delegate void DelTwo(string name);
    public delegate string  DelThree(string name);

    static void Main(string[] args)
    {
        DelOne del = delegate () { };
        DelOne del1 = () => { };
        DelTwo del2 = (string name) => { };
        DelThree del3 = (string name) => { return name; };
    }

語法2:
        List<int> list = new List<int>() { 1, 2, 3, 4, 55, 6, 7, 8, 9 };
        //lamda表示式
        list.RemoveAll(n => n > 4);
        foreach (var item in list)
        {
            Console.WriteLine(item);
        }
        Console.ReadKey();

“`