回调函数是一种非常有用的编程机制,它的存在已经有很多年了。.NET通过委托来提供回调函数机制。不同于其他平台(比如非托管C++)的回调机制,委托的功能要多得多。例如,委托确保回调方法是类型安全的(这是clr最重要的目标之一)。委托还允许顺序调用多个方法,并支持调用静态方法和实例方法。

初识委托

       c“运行时”的qsort函数获取指向一个回调函数的指针,一遍对数组中的元素进行排序。在windows中,窗口过程、钩子过程和异步过程调用等都需要回调函数。.net framework中,回调方法的应用更是广泛。例如,可以登记回调方法来获取各种各样的通知,例如未处理的异常、窗口状态变化、菜单项选择、文件系统变化、窗体控制事件和异步操作已完成等。

       在非托管C/C++中,非成员函数的地址只是一个内存地址。这个地址不携带任何额外信息,。比如函数期望收到的参数个数、参数类型、函数返回值类型以及函数调用协定。简单地说,非托管C/C++回调函数不是类型安全的(不过他们确实是一种非常轻量级的机制)。

       .NET的回调函数和非托管windows编程环境的回调函数一样有用,一样普遍。但是,.net提供了称为委托的类型安全机制。为了理解委托,先来看看如何使用它。

委托4个最基本的步骤:

1)定义委托类型

2)有一个方法包含要执行的代码(签名要与委托相同)

3)创建一个委托实例化(包含声明委托对象)

4)执行调用(invoke)委托实例

具体解释如下:

1.定义委托类型

委托类型就是参数类型的一个列表以及一个返回类型。   

delegate void StringProcessor(string input);

其中的StringProcessor是一个类型。

2.定义签名相同的方法

定义的方法要与委托有类型相同的返回值和参数。   

private void GetStringLength(object x){}  //C#2.0以后认为一致

3.创建委托实例

创建委托实例就是指定在调用委托实例时执行的方法。   

StringProcessor proc1,proc2
//GetStringLength 实例方法
proc1= new StringProcessor(GetStringLength);
//GetString 静态方法
proc2 += GetString;

4.调用委托

调用委托就是调用一个委托实例方法。  

proc1("Hello World");

以下代码演示了如何声明、创建和使用委托。

// 1.声明委托类型
internal delegate void Feedback(Int32 value);
internal class Program
{
    private static void Main(string[] args)
    {
        StaticDelegateDemo();
        InstanceDelegateDemo();
        ChainDelegateDemo1(new Program());
        ChainDelegateDemo2(new Program());

    }

    private static void StaticDelegateDemo()
    {
        Console.WriteLine("----- Static Delegate Demo -----");
        Counter(1, 3, null);
        // 3.创建委托实例
        Counter(1, 3, new Feedback(Program.FeedbackToConsole));
        Counter(1, 3, new Feedback(FeedbackToMsgBox));
        Console.WriteLine();
    }

    private static void InstanceDelegateDemo()
    {
        Console.WriteLine("----- Instance Delegate Demo -----");
        Program di = new Program();
        // 3.创建委托实例
        Counter(1, 3, new Feedback(di.FeedbackToFile));

        Console.WriteLine();
    }

    private static void ChainDelegateDemo1(Program di)
    {
        Console.WriteLine("----- Chain Delegate Demo 1 -----");
        // 3.创建委托实例
        Feedback fb1 = new Feedback(FeedbackToConsole);
        Feedback fb2 = new Feedback(FeedbackToMsgBox);
        Feedback fb3 = new Feedback(di.FeedbackToFile);

        Feedback fbChain = null;
        fbChain = (Feedback)Delegate.Combine(fbChain, fb1);
        fbChain = (Feedback)Delegate.Combine(fbChain, fb2);
        fbChain = (Feedback)Delegate.Combine(fbChain, fb3);
        Counter(1, 2, fbChain);

        Console.WriteLine();
        fbChain = (Feedback)Delegate.Remove(fbChain, new Feedback(FeedbackToMsgBox));
        Counter(1, 2, fbChain);
    }

    private static void ChainDelegateDemo2(Program di)
    {
        Console.WriteLine("----- Chain Delegate Demo 2 -----");
        Feedback fb1 = new Feedback(FeedbackToConsole);
        Feedback fb2 = new Feedback(FeedbackToMsgBox);
        Feedback fb3 = new Feedback(di.FeedbackToFile);

        Feedback fbChain = null;
        fbChain += fb1;
        fbChain += fb2;
        fbChain += fb3;
        Counter(1, 2, fbChain);

        Console.WriteLine();
        fbChain -= new Feedback(FeedbackToMsgBox);
        Counter(1, 2, fbChain);
    }

    private static void Counter(Int32 from, Int32 to, Feedback fb)
    {
        for (Int32 val = from; val <= to; val++)
        {
            // 如果指定了任何回调,就可以调用它
            if (fb != null)
                // 4.调用委托
                fb(val);
        }
    }

    // 2.声明签名相同的方法
    private static void FeedbackToConsole(Int32 value)
    {
        Console.WriteLine("Item=" + value);
    }

    // 2.声明签名相同的方法
    private static void FeedbackToMsgBox(Int32 value)
    {
        Console.WriteLine("Item=" + value);
    }

    // 2.声明签名相同的方法
    private void FeedbackToFile(Int32 value)
    {
        StreamWriter sw = new StreamWriter("Status", true);
        sw.WriteLine("Item=" + value);
        sw.Close();
    }
}
委托的简单使用

相关文章:

  • 2021-10-05
  • 2021-10-18
  • 2021-10-25
  • 2021-05-28
  • 2022-01-20
  • 2021-04-15
  • 2021-10-25
猜你喜欢
  • 2021-10-19
  • 2021-06-30
  • 2022-01-19
  • 2021-09-15
  • 2021-07-12
  • 2021-08-14
  • 2022-12-23
相关资源
相似解决方案