C Delegates 委托

C Delegates 委托C Delegates 委托通常我们都是把数据作为参数传递给方法 inti int Parse 99 当需要把方法传送给其他方法时就需要使用委托 类的用法 首先声明一个类 接着实例化一个类 委托的用法和类的用法类似 首先定义委托告诉编译器这种类型的委托表示哪种类型的方法 接着创建该委托的一个或者多个实例 声明委托委托的类型安全性非常高 在定义委托时必须给出他所表示的方法的签名

C# Delegates 委托

声明委托

根据定义委托的可见性和委托的作用域,可以在委托的定义上应用任意常见的访问修饰符:public,private,protected。

使用委托

namespace Delegates { 
    class Program { 
    // 声明委托 private delegate string GetString(); static void Main(string[] args) { 
    // 定义一个委托的实例getString GetString getString = null; int i = 99; // 给委托赋值 getString = i.ToString; Console.WriteLine($"{getString()}"); } } } 

在给委托赋值时,这个方法必须匹配委托声明时的签名,在调用时使用了类似方法的getString(),C#编译器会用getString.Invoke()代替getString()。

Action< T >和Func< T >委托

 class Program { 
    private delegate double DoubleOp(double x); static void Main(string[] args) { 
    DoubleOp[] operations = { 
    MathOpertions.MuliplyByTwo,MathOpertions.Squate}; for(int i = 0; i < operations.Length; i++) { 
    ProcessAndDisplayNumble(operations[i], 2.0); ProcessAndDisplayNumble(operations[i], 7.94); ProcessAndDisplayNumble(operations[i], 1.414); } Console.WriteLine($""); } static void ProcessAndDisplayNumble(DoubleOp action, double value) { 
    double result = action(value); Console.WriteLine($"value={value},operation result ={result}"); } } class MathOpertions { 
    public static double MuliplyByTwo(double value) => value * 2; public static double Squate(double value) => value * value; } 

上面列举了一个普通的委托实例,需要先声明一个委托,下面用Fun< double T , double T >修改上面的代码,不需要声明委托。

 static void Main(string[] args) { 
    Func<double,double>[] operations = { 
    MathOpertions.MuliplyByTwo,MathOpertions.Squate}; for(int i = 0; i < operations.Length; i++) { 
    ProcessAndDisplayNumble(operations[i], 2.0); ProcessAndDisplayNumble(operations[i], 7.94); ProcessAndDisplayNumble(operations[i], 1.414); } Console.WriteLine($""); } static void ProcessAndDisplayNumble(Func<double, double> action, double value) { 
    double result = action(value); Console.WriteLine($"value={value},{action.ToString()} result ={result}"); } } class MathOpertions { 
    public static double MuliplyByTwo(double value) => value * 2; public static double Squate(double value) => value * value; } 

多播委托

以上每个委托都只包含一个方法调用,调用委托的次数和调用 方法的次数相同。委托可以包含多个方法,如果调用多播委托,就会按照顺序连续调用多播委托中的方法。多播委托可以识别‘+’、‘+=’、‘-’、‘-=’。

 class Program { 
    static void Main(string[] args) { 
    Action<double> operations = null; operations = MathOpertions.MuliplyByTwo; operations += MathOpertions.Square; double[] arr = new double[]{ 
    2.0, 7.94, 1.414 }; foreach(var item in arr) { 
    operations(item); } Console.WriteLine($"Hello World"); } } class MathOpertions { 
    public static void MuliplyByTwo(double value) { 
    double result = value * 2; Console.WriteLine($"MuliplyByTwo value={value} reult={result}"); } public static void Square(double value) { 
    double result = value * 2; Console.WriteLine($"Square value={value} reult={result}"); } } 

多播委托顺序执行方法
使用多播委托会有一个问题:通过委托调用的其中一个方法抛出异常,整个迭代就会停止。如下代码所示,在方法中假装抛出异常:

 class Program { 
    static void Main(string[] args) { 
    Action<double> operations = null; operations = MathOpertions.MuliplyByTwo; operations += MathOpertions.Square; double[] arr = new double[]{ 
    2.0, 7.94, 1.414 }; foreach(var item in arr) { 
    operations(item); } Console.WriteLine($"Hello World"); } } class MathOpertions { 
    public static void MuliplyByTwo(double value) { 
    double result = value * 2; Console.WriteLine($"MuliplyByTwo value={value} reult={result}"); throw new Exception("this is a Exception"); } public static void Square(double value) { 
    double result = value * 2; Console.WriteLine($"Square value={value} reult={result}"); } } 

多播委托抛出异常终止迭代
解决这个问题:使用try…catch,抛出异常后循环继续

class Program { 
    static void Main(string[] args) { 
    Action<double> operations = null; operations = MathOpertions.MuliplyByTwo; operations += MathOpertions.Square; double[] arr = new double[]{ 
    2.0, 7.94, 1.414 }; foreach(var item in arr) { 
    try { 
    operations(item); }catch(Exception e) { 
    Console.WriteLine(e.Message); } } Console.WriteLine($"Hello World"); } } class MathOpertions { 
    public static void MuliplyByTwo(double value) { 
    double result = value * 2; Console.WriteLine($"MuliplyByTwo value={value} reult={result}"); throw new Exception("this is a Exception"); } public static void Square(double value) { 
    double result = value * 2; Console.WriteLine($"Square value={value} reult={result}"); } } 

多播委托抛出异常迭代继续
虽然循环继续,但是每次只执行第一个方法,因为第一个方法抛出异常后委托的迭代会停止。解决这个问题,需要自己迭代方法列表:

 class Program { 
    static void Main(string[] args) { 
    Action<double> operations = null; operations = MathOpertions.MuliplyByTwo; operations += MathOpertions.Square; Delegate[] delegates = operations.GetInvocationList(); double[] arr = new double[]{ 
    2.0, 7.94, 1.414 }; foreach(var item in arr) { 
    foreach(Action<double> d in delegates) { 
    try { 
    d(item); } catch (Exception e) { 
    Console.WriteLine(e.Message); } } } Console.WriteLine($"Hello World"); } } class MathOpertions { 
    public static void MuliplyByTwo(double value) { 
    double result = value * 2; Console.WriteLine($"MuliplyByTwo value={value} reult={result}"); throw new Exception("this is a Exception"); } public static void Square(double value) { 
    double result = value * 2; Console.WriteLine($"Square value={value} reult={result}"); } } 

委托内方法迭代

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/232867.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Android SDK 下载安装及配置[通俗易懂]

    Android SDK 下载安装及配置[通俗易懂]SDK下载安装及配置

    2022年7月19日
    16
  • A2W W2A A2T T2A _T() 含义以及用法

    A2W W2A A2T T2A _T() 含义以及用法A2W、W2A、A2T、T2A _T() 的含义及使用方法1、A2W和W2A在《Window核心编程》,多字节和宽字节之间转换比较麻烦的,MultiByteToWideChar函数和WideCharToMultiByte函数有足够多的参数的意义让我们去理解。那么使用ATL的一个很好的字符串的转换宏:A2W和W2A。char:8位字节类型,表示ASCII码WCHAR:16位字符类型,表示Un…

    2022年8月18日
    3
  • ADO.NET Entity Framework插入和更新数据(实体框架快速入门)

    ADO.NET Entity Framework插入和更新数据(实体框架快速入门)

    2021年8月9日
    49
  • 仙之侠道二九章怎么开青门_仙之侠道2玖章全面攻略

    仙之侠道二九章怎么开青门_仙之侠道2玖章全面攻略仙之侠道这一系列的图小编也玩了好几年了(初章一直到现在的六章)。都是单机或者找两个朋友玩的。六章任务中前期推荐做:可以得衣服,得钱的任务,例如:狼皮任务,包包果,巨虾甲任务,古币以及挖蘑菇(牛洞的走法下面有介绍)等。这一系列图前期的等级以及衣服是最最重要的。当然挑战系列不要忘了前期有个移动最大化的鞋子,特别实用。紧急的书信这是游戏中最简单的一个任务了,只要去找NPC接了任务拿了信,再送去南诏就可…

    2025年8月22日
    4
  • Java多线程面试题(面试必备)

    文章目录一、多线程基础基础知识1.并发编程1.1并发编程的优缺点1.2并发编程的三要素1.3并发和并行有和区别1.4什么是多线程,多线程的优劣?2.线程与进程2.1什么是线程与进程2.2线程与进程的区别2.3用户线程与守护线程2.4什么是线程死锁2.5形成死锁的四个必要条件2.6如何避免死锁3.创建线程的四种方式4.线程状态和基本操作一、多线程基础基础知识1.并发编程1.1并发编程的优缺点优点:充分利用多核CPU的计算能力,通过并发编程的形式将多核CPU的计算.

    2022年4月7日
    35
  • Java线上问题排查神器Arthas快速上手与原理浅谈

    Java线上问题排查神器Arthas快速上手与原理浅谈前言当你兴冲冲地开始运行自己的Java项目时,你是否遇到过如下问题:程序在稳定运行了,可是实现的功能点了没反应。为了修复Bug而上线的新版本,上线后发现Bug依然在,却想不通哪里有问题?想到可能出现问题的地方,却发现那里没打日志,没法在运行中看到问题,只能加了日志输出重新打包——部署——上线程序功能正常了,可是为啥响应时间这么慢,在哪里出现了问题?程序不但稳定运行,而且功能完美,但…

    2025年5月24日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号