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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • MySQL JDBC StreamResult通信原理浅析

    MySQL JDBC StreamResult通信原理浅析好几年没写技术博客了,今天写一个小的技术点给大家分享,关于MySQLJDBCStreamResult的原理分享,难度不大,就当程序员的闲聊。如果使用MySQLJDBC读取过比较大的数据(例如超过1GB),应该清楚在读取的时候,很可能会Java堆内存溢出,我们的解决方案通常是使用useCursorFetch读取或Stream读取来处理。使用Stream读取的方式通常的操作方式是在执行SQL…

    2022年7月17日
    31
  • WebRTC之ICE服务器coturn安装及部署

    WebRTC之ICE服务器coturn安装及部署GitHub:https://github.com/coturn/coturn一、安装sudoapt-getinstallcoturn

    2022年6月10日
    70
  • Android Animation之ScaleAnimation用法详解[通俗易懂]

    Android Animation之ScaleAnimation用法详解[通俗易懂]ScaleAnimation用法详解ScaleAnimation是Animation的子类,其有四个构造方法:1、publicScaleAnimation(Contextcontext,AttributeSetattrs)方法的两个参数中context就不再解释了,上下文变量,attrs是属性集。一般很少利用该构造方法构造ScaleAnimation,因为还要在XML文件里

    2022年10月16日
    2
  • iterator迭代器详解_迭代器是什么

    iterator迭代器详解_迭代器是什么迭代器 Iterator动机模式定义实例结构要点总结笔记动机在软件构建过程中,集合对象内部结构常常变化各异.但对于这些集合对象.我们希望在不暴露其内部结构地同时.可以让外部客户代码透明地访问其中包含地元素;同时这种”透明遍历”也为”同一种算法在多种集合对象上进行操作”提供了可能.使用面向对象技术将这种便利机制抽象为”迭代对象”为”应对变化中地集合对象”提供了一种优雅地方式模式定义提供了一种方法顺序访问一个聚合对象中地各个元素,而又不暴露(稳定)该对象地内部表示.实例结构要点总结迭代抽象

    2022年8月9日
    4
  • Idea激活码教程,永久有效激活码2025.1.1.1绝对有效2025.1.1.1

    Idea激活码教程,永久有效激活码2025.1.1.1绝对有效2025.1.1.1Idea 激活码教程永久有效 2025 1 1 1 激活码教程 Windows 版永久激活 持续更新 Idea 激活码 2025 1 1 1 成功激活

    2025年5月21日
    9
  • sql分别用日期、月、年 分组 group by 分组,datepart函数,datediff函数 统计

    sql分别用日期、月、年 分组 group by 分组,datepart函数,datediff函数 统计–以2013-12-1012:56:55为例–convert(nvarchar(10),CreateDate,120)=>2013-12-10–printconvert(varchar(100),getdate(),112)=>20200809–printconvert(nvarchar(20),getdate(),20)…

    2022年5月25日
    173

发表回复

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

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