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)
上一篇 2025年9月4日 下午4:01
下一篇 2025年9月4日 下午4:22


相关推荐

  • midas零基础入门教程

    midas零基础入门教程

    2026年3月15日
    2
  • ubuntu安装pycharm快捷图标_pycharm快捷方式找不到了

    ubuntu安装pycharm快捷图标_pycharm快捷方式找不到了1、首先下载pycharm安装包,从官网下载,选择专业版。2、解压到一个文件夹,打开bin文件夹,命令行下运行pycharm.sh文件。sh./pycharm.sh3、然后出现安装过程,一步一步走下去就行,如果中间问是否需要加载以前的设置(如果以前安装过),可以加也可以不加。4、激活码选择企业版,可以输入:http://idea.imsxm.com/5、完成安装。但是这样每次打开pycharm,需

    2022年8月26日
    9
  • 除了p站还有哪些站_p站以外的

    除了p站还有哪些站_p站以外的说p站,估计不知道的人已经很少了,不过今天搜罗君要说是,除了p站还有哪些站?我盲猜,应该很多人思考过这个问题了~咱们按照英文字母顺序ABCD···XYZ来说1.A站AcFun,中国第…

    2026年4月13日
    6
  • 编译器指令重排和CPU指令重排_十进制调整指令DA怎么用

    编译器指令重排和CPU指令重排_十进制调整指令DA怎么用这个知识点也是很多人说不清道不明的地方,感觉都知道,说又说不出来。为什么会这样呢?因为这几个字,很容易被当成动词去理解,其实正确的理解是当成名词,即指令重排现象。那什么时候会产生指令重排现象呢?两个阶段:1、编译期;2、运行期。编译期指令重排解释型语言是在运行期间执行编译+运行动作,所以运行效率较编译型语言低。Java既可以作为解释型语言去用,也可以作为编译型语言。但是主流的做法是当成编译型语言在…

    2022年10月8日
    4
  • Codeforces Round #274 (Div. 2) –A Expression

    Codeforces Round #274 (Div. 2) –A Expression

    2022年1月11日
    57
  • substance painter anchor point快速教程

    substance painter anchor point快速教程这个功能方便在substancepainter里通过normal和height实时影响污迹图来做细节但是步骤有些略麻烦,下面作为笔记也作为一个小教程首先需要实时绘制的图层必须在污迹图的下面可以在图层上直接绘制右击加上anchorpoint然后需要被影响的图层或是mask里面的generation,必须开启microDetails如果你需要绘制的高度图影响细…

    2022年10月8日
    5

发表回复

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

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