委托、lamda表达式..委托概念-匿名函数-泛型委托-Lamda表达式-多播委托

来源:互联网 发布:大数据架构有哪些 编辑:程序博客网 时间:2024/06/05 08:38

委托

一、什么是委托?

  将一个方法作为参数传递给另一个方法(参数类型为委托delegate)。
  声明一个委托类型。
  委托所指向的函数必须跟委托具有相同的的签名(参数个数、参数类型、返回值一样)。

二、基本的委托

  先看下面的代码,一种中文的问候方法还有种英文的问候方法,明显它们两个签名相同但函数名不同所以不能重载重载,当输入name时需要判断需要要调用那个函数。
</pre><pre name="code" class="csharp">namespace 基本的委托{    //声明一个委托指向一个函数    public delegate void DelSayHi(string name);    class Program    {        static void Main(string[] args)        {                   }        public static void SayHiChinese(string name)        {            Console.WriteLine("吃了么?" + name);        }        public static void SayHiEnglish(string name)        {            Console.WriteLine("Nice to meet you" + name);        }    }}

  接下来来看看委托的方法。
namespace 基本的委托{    //声明一个委托指向一个函数    public delegate void DelSayHi(string name);    class Program    {        static void Main(string[] args)        {            //DelSayHi del = SayHiEnglish;//new DelSayHi(SayHiEnglish);定义一个对象            //del("张三");            //Console.ReadKey(); //方法一            Test("张三", SayHiChinese);            Test("李四", 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);        }    }}

  声明一个委托类型的函数(签名与要调用的函数相同)
  DelSayHi del = SayHiEnglish; 或DelSayHi del =new DelSayHi(SayHiEnglish);   这两种方法相同目的是实例化DelSayHi创建一个委托对象指向一个,将委托的方法赋给del。运行后结果为Nice to meet you 张三。

三、匿名函数

 3.1 匿名函数:有方法名没函数名的函数。
  可以将上一个列子中方法二的主函数简化,改为
static void Main(string[] args)        {            DelSayHi del = delegate(string name)            {                Console.WriteLine("你好" + name);            };            del("张三");            Console.ReadKey();//方法二        }
  这时就可以把下面主函数定义的Text()、SayHiChainses()和SayHiEnglish()给删了。注意:匿名函数的签名也要和委托一样。当委托有返回值时,匿名函数也要有返回值。

  3.2接下来来看看Lamda表达式(简写版的匿名函数)
  static void Main(string[] args)        {            //lamda表达式    => :goes to            DelSayHi del = (string name) => { Console.WriteLine("你好" + name); };            del("张三");            Console.ReadKey();        }
  (string name):参数(当参数个数为0时,直接写“()”)。=> :goes to 。 { Console.WriteLine("你好" + name); }  :方法体(有返回值就加return  ....)。

四、泛型委托

  求数组的最大值。一个数组类型为数字,另一个为字符型(求长度)。利用匿名函数委托如下。
<pre name="code" class="csharp">
public delegate int DelCompare(object o1, object o2);    class Program    {        static void Main(string[] args)        {            //用匿名            object[] o = {"abc","fdsfdsds","fdsfdsfdsfdsfdsfds","fdsfds"};            //object result = GetMax(o, Compare2);            //object result = GetMax(o, delegate(object o1, object o2) {            //    string s1 = (string)o1;            //    string s2 = (string)o2;            //    return s1.Length - s2.Length;            //});            //用lamda            object result = GetMax(o, (object o1, object o2) =>            {                string s1 = (string)o1;                string s2 = (string)o2;                return s1.Length - s2.Length;            });            object[] oo = { 1,2,3,4,5,6,7,8,9};            object result1 = GetMax(oo, (object o1,object o2) => {                int s1 = (int)o1;                int s2 = (int)o2;                return s1 - s2;            });            Console.WriteLine(result);            Console.WriteLine(result1);            Console.ReadKey();        }        public static object GetMax(object[] nums, DelCompare del)        {            object max = nums[0];            for (int i = 0; i < nums.Length; i++)            {                //要传一个比较的方法                if (del(max, nums[i]) < 0)                {                    max = nums[i];                }            }            return max;        }
}}
  接下来就使用高大上的泛型委托,简化因类型不同的区别。把object替换为T(泛型集合Type)
   <span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;"> public delegate int DelCompare<T>(T t1, T t2);</span>// public delegate int DelCompare(object o1, object o2);    class Program    {        static void Main(string[] args)        {            int[] nums = { 1, 2, 3, 4, 5 };            int max = GetMax<int>(nums, Compare1);            Console.WriteLine(max);            string[] names = { "abcdefg", "fdsfds", "fdsfdsfdsfdsfdsfdsfdsfsd" };            string max1 = GetMax<string>(names, (string s1, string s2) =>            {                return s1.Length - s2.Length;            });            Console.WriteLine(max1);            Console.ReadKey();        }        public static T GetMax<T>(T[] nums, DelCompare<T> del)        {            T max = nums[0];            for (int i = 0; i < nums.Length; i++)            {                //要传一个比较的方法                if (del(max, nums[i]) < 0)                {                    max = nums[i];                }            }            return max;        }        public static int Compare1(int n1, int n2)        {            return n1 - n2;        }    }}

                        
如图:当调用用T定义的函数GetMax<T>时,只要把T改为string后面的T也变成了string型了。所以这个可以解决因参数类型不同但函数方法相同的调用问题。
这样大大的简化了代码。

五、Lamda表达式

  首先来看看Lamda表达式和委托的关系:
 从委托类中定义出几个对象。
    public delegate void DelOne();    public delegate void DelTwo(string name);    public delegate string DelThree(string name);    class Program    {        static void Main(string[] args)        {            DelOne del11 =delegate() { };// 没参数,没返回值            DelOne del12 = () => { };            DelTwo del21=delegate(string name) { };//有参数,没返回值            DelTwo del22 = (string name) => { };            DelThree del31 = delegate(string name) { return name; };//有参数,有返回值            DelThree del32 = (string name) => { return name; };         }     }
 从上面的代码中可以看出来del11等于del12、del21等于del22del31等于del32。即Lamda表达式时匿名委托的另一种表达形式。
实例:
从数据1,2,3,4,5,6,7,8,9中移除后五行。
List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };            list.RemoveAll(n => n > 4);            foreach (var item in list)            {                Console.WriteLine(item);            }            Console.ReadKey();

六、多播委托

namespace 多播委托{    public delegate void DelTest();//指向4个签名相同的函数    class Program    {        static void Main(string[] args)        {            DelTest del = T1;// 委托指向T1            del += T2;// 委托指向T2            del += T3;            del += T4;            del -= T3;            del -= T1;            //委托不只指向一个委托还可以指向多个函数            del();            Console.ReadKey();        }        public static void T1()        {            Console.WriteLine("我是T1");        }        public static void T2()        {            Console.WriteLine("我是T2");        }        public static void T3()        {            Console.WriteLine("我是T3");        }        public static void T4()        {            Console.WriteLine("我是T4");        }    }}


  运行结果为:
  我是T2
  我是T4




  



0 0