zoukankan      html  css  js  c++  java
  • 委托 你怎么看?

    一 前言

      对于委托给自己的感觉一直都是,知其然,而不知其所以然,而对于程序员来说,对于自己不是很了解的领域总是缺少安全感,为了有安全感于是我定好好理解一翻,

    以下是自己的一点总结,如有不对,还请在评论中指出,谢谢。

    二 自定义委托

    2.1 什么是委托

      委托和类一样是一种用户自定义的类型,但类表示的是数据的集合,而委托保存是的一个或多个方法 (精简版)。

         我觉得委托像是一个快递公司,我们只要把包裹给它,它就会帮我们送到指定的地方。而委托就是把方法赋值给它,然后在指定的地方调用委托就行了。

    2.2 委托常规操作

         对于委托的一些常规操作就不多写了,比较简单就 一代(一段代码)而过了。

      

     1        //以下代码包括了,声明,创建,调用 委托,为委托增加方法 ,移除方法
     2 
     3        //声明委托
     4         public delegate string MyDel(string name);
     5 
     6         static void Main(string[] args)
     7         {
     8             //创建委托对象, 并给委托对象赋值
     9             MyDel dele = Print;//将方法赋给委托时只需要传递方法名即可
    10             //给委托增加方法,也可以这么写
    11             //MyDel dele1 = Print;
    12             //MyDel dele2 = Write;
    13             //MyDel dele3 = dele1 + dele2;
    14             dele += Write;
    15             //给委托移除方法
    16             dele -= Write;
    17             //调用委托
    18             dele("Zery"); 
    19         }  
    20 
    21         private static string Print(string name)
    22         {
    23             return name;
    24         }
    25 
    26         private static string Write(string name)
    27         {
    28             return name;
    29         }

    2.3 匿名方法

         2.2中的代码赋给委托的方法都是 “具名方法”,可以重复使用的,如果赋给委托的方法只需要调用一次呢?定一个方法是不是太浪费了呢,

    那匿名方法就出场了,什么是匿名方法我就不解释了,看名字就知道了。写一写使匿名方法的注意点:

    1  必须要有 delegate类型关键字,

    2  必须要与委托的参数返回值匹配

    好了上代码 

    //声明委托 
    public delegate int DelegateDemos(int x);
    
    // 把匿名方法赋给委托,参数,与返回值都必须一样,还要有delegate关键字
     DelegateDemos dele3 = delegate(int x) { return x + 20; };
    
     //调用委托
      dele3(20)//返回40

    有了匿名方法后是不是感觉方便清爽很多呢 不用再去定义一个方法了少了很多代码。

    那 delegate(int x) { return x + 20; }; 这段代码能否再简化一点呢,那是肯定的 这个时候就要引入 "Lambda"表达示了 “=>”

    有了lambda表达示后可以将匿名方法转换为lambda表达示写法

    1             DelegateDemos dele3 = delegate(int x) { return x + 20; };//匿名方法
    2             DelegateDemos dele4 = (int x) => { return x + 20; };//lambda表达示
    3             //编译器还可以从委托的 中声明中知道委托参数的类型因此可以省略参数类型
    4             DelegateDemos dele4 = (x) => { return x + 20; };
    5             //如果只有一个隐式类型参数,我们可以省略周围的圆括号
    6             DelegateDemos dele4 = x => { return x + 20; };
    7             //lambda表达式表达式的主体是语句块或表达式,如果语句块包含了一个返回语句
    8             //可以将语句块,替换为return关键字后的表达式
    9             DelegateDemos dele4 = x => x + 20;

    关于Lambda表达 式的参数列表的要点如下

    1 lambda表达式的参数列表 中的参数必须在参数数量,类型和位置上与委托 相匹配。

    2 表达 式的参数列表中的参数不一定需要包含类型(比如隐式类型),除非委托 有ref 或out 参数这时类型是必须的

    3 如果只有一个参数,并且是隐式类型的周围的圆括号就可以省略,否则就是必须的

    4 如果没有参数,必须使用一组空括号

    三 .net Freamwork定义的委托

    3.1  Action泛型委托 

           Action是没有返回值的泛型委托,可以有0-16个参数

       

     1     internal class ActionDelegate
     2     {
     3         public void ActionMethod(int x)
     4         {
     5             Console.WriteLine(x + 20);
     6         }
     7     }
     8 
     9     ActionDelegate actionDelegate = new ActionDelegate();
    10     //接收0-16个参数 没有返回值
    11     Action<int> action = actionDelegate.ActionMethod;
    12     //绑定多个方法时要用 “+=”
    13     action += x => Console.WriteLine(x + 20);//匿名方法
    14     //调用时只要调用一次即可,会按绑定顺序来执行绑定的方法 
    15     action(30);

     3.2  Func 委托 

      可以有0-16个参数,但是返回类型是必须要的 如0个参数的Func委托 :Func<TResult> func  这里的TResult指得就是返回类型

     1     internal class FuncDelegate
     2     {
     3         public int FuncMethod(int x)
     4         {
     5             Console.WriteLine(x);
     6             return x;
     7         }
     8     }
     9      FuncDelegate funcDelegate = new FuncDelegate();
    10 
    11      //接收0-16个参数 最后一个参数为返回值
    12      Func<int, int> func = funcDelegate.FuncMethod;
    13 
    14      func +=  x =>  x + 20; //匿名方法
    15             
    16      int result =func(20);//接收返回值
    17      Console.WriteLine(result);

     3.3  Predicate委托

      Predicate只有一个参数,且返回值为bool类型

     1     internal class PredicateDelegate
     2     {
     3         public bool PredicateMethod(int x )
     4         {
     5             return x > 50;
     6         }
     7     }
     8      PredicateDelegate predicateDelegate = new PredicateDelegate();
     9       // 只有一个参数 并返回bool 值
    10      Predicate<int> predicate = predicateDelegate.PredicateMethod;
    11 
    12      predicate += x =>  x > 50; //匿名方法
    13             
    14      bool results =predicate(60);
    15      Console.WriteLine(results);

    四  委托综合应用

     1     internal class PeopleInfo
     2     {
     3         public int Id { get; set; }
     4 
     5         public string Name { get; set; }
     6 
     7         public int Age { get; set; }
     8     }
     9 
    10 
    11             var peopleList = new List<PeopleInfo>();
    12             peopleList.Add(new PeopleInfo() { Id = 1, Name = "Zery", Age = 20 });
    13             peopleList.Add(new PeopleInfo() { Id = 2, Name = "Zhang", Age = 25 });
    14             /*==============Action 委托===================*/
    15             //自定义委托
    16             peopleList.ForEach(delegate(PeopleInfo x) { Console.WriteLine("姓名:{0} 年龄:{1}", x.Name, x.Age); });
    17             
    18             //Action 委托
    19             Action<PeopleInfo> action = x => Console.WriteLine("姓名:{0} 年龄:{1}", x.Name, x.Age);
    20             peopleList.ForEach(action);
    21             
    22             //Lambda表达示
    23             peopleList.ForEach(o=> Console.WriteLine("姓名:{0} 年龄:{1}",o.Name,o.Age));
    24 
    25             //全部输出: 姓名:Zery 年龄:20
    26             //         姓名:Zhang 年龄:25   
    27 
    28             /*==============Func 委托=====================*/
    29             //自定义委托
    30             var deleFValue = peopleList.Where(delegate(PeopleInfo x) { return x.Name == "Zery"; });
    31             Console.WriteLine(deleFValue.FirstOrDefault().Name);
    32 
    33             //Func 委托
    34             Func<PeopleInfo, bool> func = x => x.Name=="Zery";
    35             var funcFValue = peopleList.Where(func);
    36             Console.WriteLine(funcFValue.FirstOrDefault().Name);
    37 
    38             //Lambda表达示
    39             var lamaFValue = peopleList.Where(o => o.Name == "Zery");
    40             Console.WriteLine(lamaFValue.FirstOrDefault().Name);
    41 
    42             //全部输出:"Zery"
    43              
    44 
    45             /*==============Predicate 委托================*/
    46             //自定义委托
    47             var delePValue = peopleList.Find(delegate(PeopleInfo x) { return x.Age == 25; });
    48             Console.WriteLine(delePValue.Name);
    49 
    50             //Predicate 委托 
    51             Predicate<PeopleInfo> predicate = x => x.Age == 25;
    52             var preValue = peopleList.Find(predicate);
    53             Console.WriteLine(preValue.Name);
    54 
    55             //Lambda表达示
    56             var lamPValue = peopleList.Find(o=> o.Age==25);
    57             Console.WriteLine(lamPValue.Name);
    58 
    59             //全部输出:"Zhang"

    五 总结

        当写完这篇文章时,对委托的理解有了一个较为全面的了解,扫去了自己的又一个盲区,成长的过程是缓慢的,关键在于坚持。

        如果您觉得本文有给您带来一点收获,不妨点个推荐,为我的付出支持一下,谢谢~

        如果希望在技术的道路上能有更多的朋友,那就关注下我吧,让我们一起在技术的路上奔跑

    成长在于积累

  • 相关阅读:
    [Lua]可变参数:"arg"和"..."
    三维模型obj文件的格式解析与读取
    多线程:如果在调用线程时传递参数
    C#正则表达式类Match和Group类的理解
    利用带关联子查询Update语句更新数据
    多线程:C#线程同步lock,Monitor,Mutex,同步事件和等待句柄(上)
    ASP.NET如何防止页面重复提交
    多线程:C#线程同步lock,Monitor,Mutex,同步事件和等待句柄(中)
    委托和事件:从猫和老鼠的故事看事件
    .NET Remoting学习点滴(一):简单示例
  • 原文地址:https://www.cnblogs.com/zery/p/3337870.html
Copyright © 2011-2022 走看看