zoukankan      html  css  js  c++  java
  • DoNet:浅淡对delegate的理解

    1 前言

    C#的相关文档,MSDN上其实已经很详细了,关于delegate的使用可以参
    考MSDN上的文档https://msdn.microsoft.com/zh-cn/library/900fyy8e.aspx

    2 官方示例

    委托类型的声明与方法签名相似, 有一个返回值和任意数目任意类型的参数:

    public delegate void TestDelegate(string message);
    public delegate int TestDelegate(MyType m, long num);

    delegate 是一种可用于封装命名或匿名方法的引用类型。 委托类似于 C++ 中的函数指针;但是,委托是类型安全和可靠的。 有关委托的应用,请参见委托和泛型委托。

    备注
    委托是事件的基础。通过将委托与命名方法或匿名方法关联,可以实例化委托。 有关更多信息,请参见命名方法和匿名方法。必须使用具有兼容返回类型和输入参数的方法或 lambda 表达式实例化委托。 有关方法签名中允许的差异程度的更多信息,请参见委托中的变体(C# 和 Visual Basic)。 为了与匿名方法一起使用,委托和与之关联的代码必须一起声明。 本节讨论这两种实例化委托的方法。

    C#示例

    // Declare delegate -- defines required signature:
    delegate double MathAction(double num);
    
    class DelegateTest
    {
        // Regular method that matches signature:
        static double Double(double input)
        {
            return input * 2;
        }
        static void Main()
        {
            // Instantiate delegate with named method:
            MathAction ma = Double;
    
            // Invoke delegate ma:
            double multByTwo = ma(4.5);
            Console.WriteLine("multByTwo: {0}", multByTwo);
    
            // Instantiate delegate with anonymous method:
            MathAction ma2 = delegate(double input)
            {
                return input * input;
            };
    
            double square = ma2(5);
            Console.WriteLine("square: {0}", square);
    
            // Instantiate delegate with lambda expression
            MathAction ma3 = s => s * s * s;
            double cube = ma3(4.375);
    
            Console.WriteLine("cube: {0}", cube);
        }
        // Output:
        // multByTwo: 9
        // square: 25
        // cube: 83.740234375
        }

    3 个人见解

    3.1 C语言函数指针

    以下代码简单实现了C语言中的函数指针

    #include <iostream>
    using namespace std;
    
    //this is likely to "delegate"
    typedef void(*func)(void);
    
    //this is likely to "event"
    func event;
    
    void CallBack()
    {
        cout << "Callback start running" << endl;   
    }
    
    int main()
    {
        event= CallBack;
        event();
    }

    一、typedef void(*func)(void); 定义了一个返回为void,传入参数为void的函数指针类型,类似于C#中的delegate;
    二、func enent; 定义了一个名为event的函数指针变量;
    三、主函数中将回调函数CallBack的地址赋值给event这个变量,event();即执行回调函数 CallBack()

    运行结果

    这里写图片描述

    3.2 C#个人示例

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace CsharpCallback
    {
    
        class Program
        {
            public delegate void Handler(int i);
            public event Handler EventRegister;
            void CallBack(int i)
            {
                Console.WriteLine("Callback is running " + i);
            }   
            void CallTest(int i)
            {
                Console.WriteLine("Calltest is running " + i);
            }
            void RegisetCallback()
            {
                EventRegister += new Handler(CallBack);
                EventRegister += new Handler(CallTest);                 
            }     
            static void Main(string[] args)
            {
                Program test = new Program();
                test.RegisetCallback();
                for (int i=0; i<100; i++)
                {
                    if(i == 50)
                    {
                        test.EventRegister(i);
                    }
                }          
            }
        }
    }

    程序分析:
    一、 public delegate void Handler(int i); 这里申明了一个名为Handler 委托,当然类似于C中的函数指针,可以参考C代码的示例加以理解,同样的,对于回调函数类型需要和委托相同;
    二、public event Handler EventRegister; 这里我理解为定义了一个函数指针的变量(这个理解可能欠妥当),event的具体使用,可以参考官方文档https://msdn.microsoft.com/zh-cn/library/8627sbea.aspx
    三、RegisetCallback() 函数则将回调函数的指针赋值给指针变量。
    程序运行结果:
    这里写图片描述

    4 总结

    粗浅的认识了一下C#中的delegate和event的简单用法,并将其与C++中的函数指针做了对比,发现存在相似之处,event的详细使用可以在MSDN上参考官方文档,这方面做的很不错,由于作者水平和能力有限,文中必有错误或者不恰当处,请各位多多指教

  • 相关阅读:
    HDU-5818-Joint Stacks
    蓝桥杯-2016CC-卡片换位
    HDU-2255-奔小康赚大钱(KM算法)
    蓝桥杯-PREV31-小朋友排队
    crypto.js加密传输
    js之对象
    LigerUi之ligerMenu 右键菜单
    关于js中window.location.href,location.href,parent.location.href,top.location.href的用法
    设置js的ctx
    AngularJS简单例子
  • 原文地址:https://www.cnblogs.com/unclemac/p/12783449.html
Copyright © 2011-2022 走看看