學習筆記之Func與Action委託泛型介紹

      .Net 3.5之後,微軟推出了Func<T>與Action<T>泛型委託。進一步簡化了委託的定義。 

  Action<T>委託主要的表現形式如下:

        public delegate void Action();
        public delegate void Action<T1>(T1 arg1);
        public delegate void Action<T1, T2>(T1 arg1, T2 arg2);
        public delegate void Action<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3);
        public delegate void Action<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
        public delegate void Action<T1, T2, T3, T4, T5>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);

  從Action<T>的定義形式上可以看到。Action<T>是沒有返回值得。適用於任何沒有返回值得方法。例如:

複製代碼
/// <summary>
        /// 應用程序的主入口點。
        /// </summary>
        [STAThread]
        static void Main()
        {
            //同步執行
            Action Action = new Action(writeLine);
            Action.Invoke();
            //異步執行
            Action ActionAsy = new Action(writeLine2);
            ActionAsy.BeginInvoke(resual=>Console.WriteLine("異步執行結束"), null);
            Console.Read();
        }
        private static void writeLine()
        {
            Console.WriteLine("Action同步執行委託");
        }
        private static void writeLine2()
        {
            Console.WriteLine("Action異步執行委託");
        }
複製代碼

  如果調用Lambda表達式,可以更簡練,對上面的代碼,可以這樣寫:

複製代碼
/// <summary>
        /// 應用程序的主入口點。
        /// </summary>
        [STAThread]
        static void Main()
        {
            //同步執行 用Lambda表達式代替writeLine
            Action Action = new Action(()=>Console.WriteLine("Action同步執行委託"));
            Action.Invoke();
            //異步執行 用Lambda表達式代替writeLine2
            Action ActionAsy = new Action(()=>Console.WriteLine("Action異步執行委託"));
            ActionAsy.BeginInvoke(resual=>Console.WriteLine("異步執行結束"), null);
            Console.Read();
        }
        private static void writeLine()
        {
            Console.WriteLine("Action同步執行委託");
        }
        private static void writeLine2()
        {
            Console.WriteLine("Action異步執行委託");
        }
複製代碼

  如果有參數需要傳入,Action<T>可以這麼做,例如:

複製代碼
/// <summary>
        /// 應用程序的主入口點。
        /// </summary>
        [STAThread]
        static void Main()
        {
            //同步執行 傳入一個參數
            Action<string> Action = new Action<string>((a)=>Console.WriteLine(string.Format("Action同步執行委託,傳入參數:{0}",a)));
            Action.Invoke("小李");
            //異步執行 傳入兩個參數
            Action<string,int> ActionAsy = new Action<string,int>((a,b)=>Console.WriteLine("Action異步執行委託,傳入參數:{0},{1}",a,b));
            ActionAsy.BeginInvoke("小李",12,resual=>Console.WriteLine("異步執行結束"), null);
            Console.Read();
        }
複製代碼

  在上面代碼中,同步定義的string類型,必須保證傳入的參數a也是string雖然並沒有對a進行類型定義,但是系統默認就是事先泛型中定義的類型。類似的,異步委託也是一樣。不然會報錯。

   Func<T>委託主要的表現形式如下:

  

        public delegate TResult Func<TResult>();
        public delegate TResult Func<T1, TResult>(T1 arg1);
        public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
        public delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
        public delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
        public delegate TResult Func<T1, T2, T3, T4, T5, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);

  Func<T>委託的定義是相對於Action<T>來說。Action<T>是沒有返回值得方法委託,Func<T>是有返回值的委託。返回值的類型,由泛型中定義的類型進行約束。例如:

  

複製代碼
        /// <summary>
        /// 應用程序的主入口點。
        /// </summary>
        [STAThread]
        static void Main()
        {
            //異步執行 
            Func<string> FuncAsy = new Func<string>(() =>
            {
                people tPeo = new people("異步小李", 10);
                return tPeo.ToString();
            }
            );
            FuncAsy.BeginInvoke(resual =>
                {
                    //異步執行,從回調函數中獲取返回結果
                    Console.WriteLine(FuncAsy.EndInvoke(resual));
                    Console.WriteLine("異步執行結束");
                }, null);
            //同步執行 
            Func<string> Func = new Func<string>(() =>
            {
                people tPeo = new people("同步小李", 12);
                return tPeo.ToString();
            }
            );
            //同步執行,獲取返回結果
            Console.WriteLine(Func.Invoke());
            Console.Read();
        }
        public class people
        {
            public string Name { get; set; }
            public int Age { get; set; }
            public people(string pName, int pAge)
            {
                this.Name = pName;
                this.Age = pAge;
            }
            public override string ToString()
            {
                return string.Format("名稱叫{0},年齡{1}", this.Name, this.Age);
            }
        }
複製代碼

  輸出結果如下:
  

  如果有參數,可以這樣寫:

 

複製代碼
        /// <summary>
        /// 應用程序的主入口點。
        /// </summary>
        [STAThread]
        static void Main()
        {
            //異步執行 傳入一個people類型的參數,返回一個sting類型的結果
            Func<people, string> FuncAsy = new Func<people, string>((pPeople) =>
            {
                return pPeople.Name;
            }
            );
            FuncAsy.BeginInvoke(new people("異步小李", 12), resual =>
                {
                    //異步執行,從回調函數中獲取返回結果
                    Console.WriteLine(FuncAsy.EndInvoke(resual));
                    Console.WriteLine("異步執行結束");
                }, null);
            //同步執行 傳入一個string,int類型的參數,返回一個people類型的結果
            Func<string, int, people> Func = new Func<string, int, people>((pName,pAge) =>
            {
                people tPeo = new people(pName, pAge);
                return tPeo;
            }
            );
            //同步執行,返回結果
            Console.WriteLine(Func.Invoke("同步小李",12).ToString());
            Console.Read();
        }
複製代碼

 

 

 

作者: cglnet
本文版權歸cglNet和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章