博客
关于我
委托-利用GetInvocationList处理链式委托
阅读量:582 次
发布时间:2019-03-11

本文共 2591 字,大约阅读时间需要 8 分钟。

在C#中,当使用委托代理多个函数时,如果每次都使用+=来添加新的函数到同一个委托链中,可能会遇到一个问题:每次添加新的函数都会覆盖之前的委托,导致最终只能看到最后一个函数的返回值。为了正确地获取所有函数的返回值,可以使用GetInvocationList方法来遍历委托链中的所有函数。

以下是详细的解决方案:

  • 定义委托和类

    • 定义一个委托TestDelegate,其返回类型为string
    • 创建一个类DelegateClass,包含一个TestDelegate类型的属性testDelegate
  • 在Main方法中创建函数实例并添加到委托链

    • 创建四个不同的函数实例onetwothreefour,它们都实现了Say方法,返回不同的字符串。
    • 使用+=操作符将每个函数的Say方法添加到DelegateClasstestDelegate属性中。
  • 调用委托并遍历所有函数

    • DelegateClass类中实现InvokeDelegate方法。
    • InvokeDelegate方法中,检查testDelegate是否不为空。
    • 如果不为空,使用GetInvocationList方法获取委托链中的所有函数。
    • 遍历每个函数,逐个转换为TestDelegate类型并调用,获取返回值。
    • 打印每个返回值。
  • 完整代码示例

    using System;namespace GetInvocationListDemo{    public delegate string TestDelegate();    public class Program    {        static void Main(string[] args)        {            DelegateClass delegateClass = new DelegateClass();            TestMethodOne one = new TestMethodOne();            TestMethodTwo two = new TestMethodTwo();            TestMethodThree three = new TestMethodThree();            TestMethodFour four = new TestMethodFour();            delegateClass.testDelegate += one.Say;            delegateClass.testDelegate += two.Say;            delegateClass.testDelegate += three.Say;            delegateClass.testDelegate += four.Say;            delegateClass.InvokeDelegate();            Console.ReadKey();        }    }    public class DelegateClass    {        public TestDelegate testDelegate;        public void InvokeDelegate()        {            if (testDelegate != null)            {                foreach (Delegate dele in testDelegate.GetInvocationList())                {                    TestDelegate delegateClass = (TestDelegate)dele;                    string resultStr = delegateClass();                    Console.WriteLine(resultStr);                }            }        }    }    public class TestMethodOne    {        public string Say()        {            return "You called me from TestMethodOne~~~";        }    }    public class TestMethodTwo    {        public string Say()        {            return "You called me from TestMethodTwo~~~";        }    }    public class TestMethodThree    {        public string Say()        {            return "You called me from TestMethodThree~~~";        }    }    public class TestMethodFour    {        public string Say()        {            return "You called me from TestMethodFour~~~";        }    }}
  • 运行结果

    • 执行上述代码时,会依次输出四个方法的返回值:
      You called me from TestMethodOne~~~You called me from TestMethodTwo~~~You called me from TestMethodThree~~~You called me from TestMethodFour~~~
  • 通过使用GetInvocationList方法,可以确保所有添加到委托链中的函数都会被调用并获取其返回值,从而避免只保留最后一个函数的结果。

    转载地址:http://pdlvz.baihongyu.com/

    你可能感兴趣的文章
    OpenCV与AI深度学习 | 基于OpenCV和深度学习预测年龄和性别
    查看>>
    OpenCV与AI深度学习 | 基于OpenCV实现模糊检测 / 自动对焦
    查看>>
    OpenCV与AI深度学习 | 基于Python和OpenCV将图像转为ASCII艺术效果
    查看>>
    OpenCV与AI深度学习 | 基于PyTorch实现Faster RCNN目标检测
    查看>>
    OpenCV与AI深度学习 | 基于PyTorch语义分割实现洪水识别(数据集 + 源码)
    查看>>
    OpenCV与AI深度学习 | 基于YOLO11的车体部件检测与分割
    查看>>
    OpenCV与AI深度学习 | 基于YoloV11自定义数据集实现车辆事故检测(有源码,建议收藏!)
    查看>>
    OpenCV与AI深度学习 | 基于YOLOv8 + BotSORT实现球员和足球检测与跟踪 (步骤 + 源码)
    查看>>
    OpenCV与AI深度学习 | 基于YOLOv8实现高级目标检测和区域计数
    查看>>
    VS2003 Front Page Server Extension
    查看>>
    OpenCV与AI深度学习 | 基于YOLOv8的停车对齐检测
    查看>>
    OpenCV与AI深度学习 | 基于YoloV8的药丸/片剂类型识别
    查看>>
    OpenCV与AI深度学习 | 基于YOLO和EasyOCR从视频中识别车牌
    查看>>
    OpenCV与AI深度学习 | 基于图像处理的火焰检测算法(颜色+边缘)
    查看>>
    OpenCV与AI深度学习 | 基于拉普拉斯金字塔实现图像融合(步骤 + 代码)
    查看>>
    OpenCV与AI深度学习 | 基于改进YOLOv8的景区行人检测算法
    查看>>
    OpenCV与AI深度学习 | 基于机器视觉的磁瓦表面缺陷检测方案
    查看>>
    OpenCV与AI深度学习 | 基于深度学习的轮胎缺陷检测系统
    查看>>
    OpenCV与AI深度学习 | 如何使用YOLO-World做目标检测
    查看>>
    OpenCV与AI深度学习 | 如何使用YOLOv9分割图像中的对象
    查看>>