多播委托的使用举例、出现异常时多播委托需要用迭代方法列表、匿名方法、lambda表达式

多播委托:

是指委托可以包含多个方法,如果调用多播委托,可以按顺序连续调用多个方法。为此,委托的签名就必须返回void,否则,就只能得到委托调用的最后一个方法的结果。多播中添加方法操作可以使用+=

举例:

namespace Ado_net_demo1
{
    class ClassOperater
    {
      public static void One()
        {
            Console.WriteLine("One");
            throw new Exception("Error in one");
        }
        public static void Two()
      {
          Console.WriteLine("two");
      }
    }
}


执行:

namespace Ado_net_demo1
{
    class Program
    {
        static void Main()
        {
            Action del = ClassOperater.One;
            del += ClassOperater.Two;//这种方法在发生异常后停止迭代,不继续向下执行
            try
            {
                del();
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex);
            }

            Console.ReadKey();
        }       
    }
}


多播委托的改进

为了避免发生异常后,后面的委托不能执行的情况,应自己迭代方法列表,使用Delegate类定义GetInvocationList()方法,返回一个Delegate对象数组;使用这个委托调用与委托直接相关的方法,捕获异常,并继续下一次迭代。

修改

namespace Ado_net_demo1
{
    class Program
    {
        static void Main()
        {
            Action del = ClassOperater.One;
            del += ClassOperater.Two;
            Delegate[] delegates = del.GetInvocationList();
            foreach (Action d  in delegates)
            {
                try
                {
                    d();
                }
                catch (System.Exception ex)
                {
                    Console.WriteLine(ex);//当程序出现异常后,抛出,继续循环
                }
            }
            Console.ReadKey();
        }       
    }
}


匿名方法并没有提高代码的执行效率,如果需要用匿名方法多写编写同一个功能,就不要使用匿名方法。

匿名方法:

两个原则:

1、匿名方法中不能使用跳转语句(break goto continue)跳到该匿名方法的外部,反之亦然,匿名方法外部的跳转语句不能跳到匿名方法的内部;

2、匿名方法内部不能访问不安全的代码,也不能访问在匿名方法外部使用的ref和out参数,但是可以使用在匿名方法外部定义的其他变量。

    class Program
    {
        static void Main()
        {
            string mid = ",mid part";
            Func<string, string> anonDel = delegate(string param)//anonDel是委托类型的变量
            {
                param += mid;//使用到了匿名方法外定义的变量mid
                param += " and this is added to the string";
                return param;
            };
            Console.WriteLine(anonDel("hello"));//hello,mid part and this is added to the string
            Console.ReadKey();
        }       
    }

lambda表达式:

        static void Main()
        {
            string mid = ",mid part";
            Func<string, string> lambda =  param=>//lambda表达式,param是表达式的参数,返回值由return返回,这里lambda是表达式的名字,自己定义
            {
                param += mid;//使用到了表达式外定义的变量mid
                param += " and this is added to the string";
                return param;//Func<>必须有一个返回值,所有lambda表达式中必须有个return
            };
            Console.WriteLine(lambda("hello"));//hello,mid part and this is added to the string,使用表达式的名字进行定义
            Console.ReadKey();
        }


lambda的表达式的返回值:对于double型,没有return,却能得到返回值,Func<>中必须有返回值,很显然满足这个条件,但是string中必须有return,否则有错误(原因见下面)

        static void Main()
        {
            Func<double, double, double> twoParams = (x, y) => x * y;//为什么这里没有return,却能得到返回值
            Console.WriteLine(twoParams(2, 3));//6

            Console.ReadKey();
        }

关于上面的问题终于明白:lambda表达式只有一条语句,在方法块内就不需要花括号和return语句,编译器会自动添加一条隐式的return语句。多条语句需要花括号和return。

        static void Main()
        {
            //lambda表达式只有一条语句,在方法块内就不需要花括号和return语句,编译器会自动添加一条隐式的return语句
            Func<double, double, double> twoParams = (x, y) => x* y; 
            Console.WriteLine(twoParams(2, 3));//6
           
            Func<string, string> lambda3 = (param1) =>param1 += "hello";

            Console.WriteLine(lambda3("hello")); //hellohello  
            
            Console.ReadKey();
        } 

了解lambda表达式

        static void Main()
        {
            var values = new List<int>() {10,20,30 };
            var funcs = new List<Func<int>>(); //元素为Func<int>委托对象的集合
            //向集合funcs中添加委托对象,每个委托对象执行的方法就是返回values中的元素
            foreach (var val in values)
            {    
                funcs.Add(()=>val);
            }
            //遍历调用funcs集合中的每个委托
            foreach (var f in funcs)
            {
                Console.WriteLine(f());
            }
            Console.ReadKey();
        } 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一枚努力的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值