Func<T>与Action<T>委托泛型


    Func与Action委托泛型介绍

  .Net 3.5之后,微软推出了Func与Action泛型委托。进一步简化了委托的定义。 

  Action委托主要的表现形式如下:

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

  从Action的定义形式上可以看到。Action是没有返回值得。适用于任何没有返回值得方法。例如:

/// 
        /// 应用程序的主入口点。
        /// 
        [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表达式,可以更简练,对上面的代码,可以这样写:

/// 
        /// 应用程序的主入口点。
        /// 
        [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可以这么做,例如:

/// 
        /// 应用程序的主入口点。
        /// 
        [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委托主要的表现形式如下:

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

  Func委托的定义是相对于Action来说。Action是没有返回值得方法委托,Func是有返回值的委托。返回值的类型,由泛型中定义的类型进行约束。例如:

        /// 
        /// 应用程序的主入口点。
        /// 
        [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);
            }
        }

  输出结果如下:
  

  如果有参数,可以这样写:

        /// 
        /// 应用程序的主入口点。
        /// 
        [STAThread]
        static void Main()
        {
            //异步执行 传入一个people类型的参数,返回一个sting类型的结果
            Funcstring> FuncAsy = new Funcstring>((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();
        }
            #region Predicate
//bool Predicate的用法 //输入一个T类型的参数,返回值为bool类型 Predicate predicate = new Predicate((string[] x) => { var result = from p in x where p.Contains("s") select p; bool isSuccess = false; if (result.ToList().Count > 0) isSuccess = true; return isSuccess; }); string[] _value = { "charlies", "nancy", "alex", "jimmy", "selina" }; if (predicate(_value)) Console.WriteLine("They contain."); else Console.WriteLine("They don't contain."); Console.ReadLine(); //bool Predicate的用法 //输入一个T类型的参数,返回值为bool类型 Predicate predicate = delegate(string[] x) { var result = from p in x where p.Contains("s") select p; if (result.ToList().Count > 0) { return true; } else { return false; } }; string[] _value = { "charlies", "nancy", "alex", "jimmy", "selina" }; if (predicate(_value)) { Console.WriteLine("They contain."); } else { Console.WriteLine("They don't contain."); } Console.ReadKey();
       #endregion

文章摘自:作者: cglnet 出处: http://www.cnblogs.com/cglnet