[C#] C# 知识回顾 - 委托 delegate美高梅4858官方网站

作者:编程技术

使用委托

  委托,一种类型,它是安全的,自定义的,委托的名称就决定了这个委托是什么类型。

    //该委托可以封装 “,参数类型 string,返回类型 void” 的方法 
    public delegate void MyDel(string message);

 

  委托的实例对象通常使用两种方式进行构建,直接使用类的方法名,或者使用 Lambda 表达式,当然匿名方法也可以。

  在调用委托的时刻,我们将传递到委托的参数会继续传递到委托列表的方法中。如果委托列表中包含返回值的话,会将最后一个返回值返回给调用方。也就是该委托对象调用完毕的返回值。

 1     //该委托名为 MyDel,可以封装 “参数类型 string,返回值类型 void” 的方法 
 2     public delegate void MyDel(string message);
 3 
 4     class Program
 5     {
 6         static void Main(string[] args)
 7         {
 8             //实例化委托
 9             MyDel del = Print;
10             //调用委托
11             del("Hi");
12 
13             Console.Read();
14         }
15 
16         /// <summary>
17         /// 打印文本
18         /// </summary>
19         /// <remarks>这是一个可用于 MyDel 委托的方法</remarks>
20         /// <param name="message"></param>
21         private static void Print(string message)
22         {
23             Console.WriteLine(message);
24         }
25     }

美高梅4858官方网站 1

  委托的关键字是 delegate,它派生自 Delegate 类,也是 sealed,即密封类,不能作为基类再继续派生。

  异步回调:允许以方法的形式作为参数形式进行传递,并在稍后进行该委托的调用。通过这个形式使用的委托,调用方不需要知道方法的具体实现,只是简单的把它当做一个功能即可,这类似接口的封装。

 

  简单的异步回调方法演示:

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             MyDel del = Print;
 6             CallbackMethod(100, 150, del);  //将委托传递到 CallbackMethod 方法
 7 
 8             Console.Read();
 9         }
10 
11         /// <summary>
12         /// 回调方法
13         /// </summary>
14         /// <param name="m"></param>
15         /// <param name="n"></param>
16         /// <param name="del"></param>
17         private static void CallbackMethod(int m, int n, MyDel del)
18         {
19             del((m   n).ToString());
20         }
21 
22         private static void Print(string message)
23         {
24             Console.WriteLine(message);
25         }
26     }

美高梅4858官方网站 2

 

  在这里的 CallbackMethod 作用是,调用委托,因为它包含的是 Print() 方法的调用,所以只需要传递对应的 string 类型作为参数即可。

 

  我们在创建委托的时候,你可以选择使用的是实例方法或者是静态方法。当你使用的是实例方法时,该委托对象会同时引用该实例的对象及它的方法。委托并不关心应用引用对象的类型,它关心的是,方法签名和返回值兼容,即可。不过,如果你创建委托对象包含的是静态方法的时候,它是只引用该方法的。

  使用 = 可以把多个方法添加到一个委托对象的调用列表中,调用一次委托,相当于一次性调用一堆方法。

 1     //该委托可以封装 “名 MyDel,参数类型 string,返回值类型 void” 的方法 
 2     public delegate void MyDel(string message);
 3 
 4     class MyClass
 5     {
 6         public void Print1(string message)
 7         {
 8             Console.WriteLine($"{message} - {nameof(Print1)}");
 9         }
10 
11         public void Print2(string message)
12         {
13             Console.WriteLine($"{message} - {nameof(Print2)}");
14         }
15     }
16 
17     class Program
18     {
19         static void Main(string[] args)
20         {
21             var myClass = new MyClass();
22             MyDel del1 = myClass.Print1;
23             MyDel del2 = myClass.Print2;
24             MyDel del3 = Print;
25 
26             var del = del1   del2;
27             del  = del3;    //这里使用  =
28             del("Hi!");
29 
30             Console.Read();
31         }
32 
33         private static void Print(string message)
34         {
35             Console.WriteLine($"{message} - {nameof(Print)}");
36         }
37     }

美高梅4858官方网站 3

   委托对象 del,他内部存储的是一个包含三个方法的调用列表(Print1、Print2 和 Print),在你调用 del 对象时,调用列表中的方法会依次调用。

  

  多播委托:一个委托对象调用多个方法,使用 =。

  若要从委托对象的调用列表中移除方法,需要使用 -=。

 

 1         static void Main(string[] args)
 2         {
 3             var myClass = new MyClass();
 4             MyDel del1 = myClass.Print1;
 5             MyDel del2 = myClass.Print2;
 6             MyDel del3 = Print;
 7 
 8             var del = del1   del2;
 9             del  = del3;    //使用  =
10             del("Hi!");
11 
12             Console.WriteLine("======分割线======");
13 
14             del -= del2;    //使用 -=
15             del("Hi!");
16 
17             Console.Read();
18         }

美高梅4858官方网站 4

 

  你也可以编写一些方法获取调用列表中方法的数量:

 1         static void Main(string[] args)
 2         {
 3             var myClass = new MyClass();
 4             MyDel del1 = myClass.Print1;
 5             MyDel del2 = myClass.Print2;
 6             MyDel del3 = Print;
 7 
 8             var del = del1   del2;
 9             del  = del3;    //使用  =
10             //del("Hi!");
11 
12             var count = del.GetInvocationList().Length; //获取委托调用列表中方法的数量
13             Console.WriteLine(count);
14 
15             Console.WriteLine("======分割线======");
16 
17             del -= del2;    //使用 -=
18             //del("Hi!");
19 
20             count = del.GetInvocationList().Length; //获取委托调用列表中方法的数量
21             Console.WriteLine(count);
22 
23             Console.Read();
24         }

美高梅4858官方网站 5

 

  多播委托派生自 MulticastDelegate,也是继承自 Delegate的,常用于事件处理中。

 

What's 委托

  delegate 是表示对具有特定参数列表和返回类型的方法的引用的类型。在实例化委托时,你可以将其实例与任何具有兼容签名和返回类型的方法相关联。你可以通过委托实例调用方法。委托用于将方法作为参数传递给其他方法。事件处理程序就是通过委托调用的方法。你可以创建一个自定义方法,当发生特定事件时,某个类(如 Windows 控件)就可以调用你的方法。

  下面的示例演示了一个委托声明:

public delegate int Del(int x, int y);

  可将任何可访问类或结构中与委托类型匹配的任何方法分配给委托。该方法可以是静态方法,也可以是实例方法。这样便能通过编程方式来更改方法调用,还可以向现有类中插入新代码。

  【备注】在方法重载的上下文中,方法的签名不包括返回值。但在委托的上下文中,签名包括返回值。换句话说,方法和委托必须具有相同的返回类型。

  将方法作为参数进行引用的能力使委托成为定义回调方法的理想选择。例如,对比较两个对象的方法的引用可以作为参数传递到排序算法中。由于比较代码在一个单独的过程中,因此可通过更常见的方式编写排序算法。

 

委托的特点

  • 类型安全,类似于 C 和 C 中的函数指针。

  • 可将方法作为参数进行传递。

  • 可用于定义回调方法。

  • 委托可以链接在一起;例如,可以对一个事件调用多个方法。

  • 方法不必与委托类型完全匹配。

 

目录

  • What's 委托
  • 委托的属性概述
  • Use 委托

 

目录

  • What's 委托
  • 委托的特点
  • 使用委托

 

[C#] C# 知识回顾,

传送门

  《C# 知识回顾 - 序列化》

  《C# 知识回顾 - 表达式树 Expression Trees》

  《C# 知识回顾 - 特性 Attribute》、《剖析 AssemblyInfo.cs - 了解常用的特性 Attribute》

 

 


【参考】

【参考】微软官方文档

Use 委托

  委托是安全封装方法的类型,类似于 C 和 C 中的函数指针。与 C 函数指针不同的是,委托是面向对象的、类型安全的和可靠的。委托的类型由委托的名称确定。

    //该委托可以封装 “,参数类型 string,返回类型 void” 的方法 
    public delegate void MyDel(string message);

 

  委托对象通常通过提供委托将封装的方法的名称或使用匿名方法构造。对委托进行实例化后,委托会将对其进行的方法调用传递到该方法。调用方传递到委托的参数将传递到该方法,并且委托会将方法的返回值(如果有)返回到调用方。这被称为调用委托。实例化的委托可以按封装的方法本身进行调用。例如:

 1     //该委托名为 MyDel,可以封装 “参数类型 string,返回值类型 void” 的方法 
 2     public delegate void MyDel(string message);
 3 
 4     class Program
 5     {
 6         static void Main(string[] args)
 7         {
 8             //实例化委托
 9             MyDel del = Print;
10             //调用委托
11             del("Hi");
12 
13             Console.Read();
14         }
15 
16         /// <summary>
17         /// 打印文本
18         /// </summary>
19         /// <remarks>这是一个可用于 MyDel 委托的方法</remarks>
20         /// <param name="message"></param>
21         private static void Print(string message)
22         {
23             Console.WriteLine(message);
24         }
25     }

异步回调,是在长进程完成时通知调用方的常用方法。当以这种方式使用委托时,使用委托的代码不需要知道要使用的实现方法。功能类似于封装接口提供的功能。       回调的另一个常见用途是定义自定义比较方法并将该委托传递到短方法。  它允许调用方的代码成为排序算法的一部分。  以下示例方法使用 Del 类型作为参数:  

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             MyDel del = Print;
 6             CallbackMethod(100, 150, del);  //将委托传递到 CallbackMethod 方法
 7 
 8             Console.Read();
 9         }
10 
11         /// <summary>
12         /// 回调方法
13         /// </summary>
14         /// <param name="m"></param>
15         /// <param name="n"></param>
16         /// <param name="del"></param>
17         private static void CallbackMethod(int m, int n, MyDel del)
18         {
19             del((m   n).ToString());
20         }
21 
22         private static void Print(string message)
23         {
24             Console.WriteLine(message);
25         }
26     }

委托不知道除其所封装方法以外的实例类型,因此委托可以引用任何类型的对象,只要该对象上有与委托签名匹配的方法。当委托构造为封装静态方法时,委托仅引用方法。  请考虑以下声明:  

 1     //该委托可以封装 “名 MyDel,参数类型 string,返回值类型 void” 的方法 
 2     public delegate void MyDel(string message);
 3 
 4     class MyClass
 5     {
 6         public void Print1(string message)
 7         {
 8             Console.WriteLine($"{message} - {nameof(Print1)}");
 9         }
10 
11         public void Print2(string message)
12         {
13             Console.WriteLine($"{message} - {nameof(Print2)}");
14         }
15     }
16 
17     class Program
18     {
19         static void Main(string[] args)
20         {
21             var myClass = new MyClass();
22             MyDel del1 = myClass.Print1;
23             MyDel del2 = myClass.Print2;
24             MyDel del3 = Print;
25 
26             var del = del1   del2;
27             del  = del3;    //这里使用  =
28             del("Hi!");
29 
30             Console.Read();
31         }
32 
33         private static void Print(string message)
34         {
35             Console.WriteLine($"{message} - {nameof(Print)}");
36         }
37     }

多播。若要向委托的方法列表(调用列表)添加其他方法,只需使用加法运算符或加法赋值运算符(“ ”或“ =”)添加两个委托。

  此时,del 的调用列表中包含三个方法,分别为 Print1、Print2 和 Print。原有的三个委托(del1、del2 和 del3)保持不变。调用 allMethodsDelegate 时,将按顺序调用所有三个方法。如果委托使用引用参数,引用将按相反的顺序传递到所有这三个方法,并且一种方法进行的任何更改都将在另一种方法上见到。当方法引发未在方法内捕获到的异常时,该异常将传递到委托的调用方,并且不会调用调用列表中的后续方法。如果委托具有返回值和/或输出参数,它将返回上次调用方法的返回值和参数。若要删除调用列表中的方法,请使用减法运算符或减法赋值运算符(“-”或“-=”)。  例如:  

 1         static void Main(string[] args)
 2         {
 3             var myClass = new MyClass();
 4             MyDel del1 = myClass.Print1;
 5             MyDel del2 = myClass.Print2;
 6             MyDel del3 = Print;
 7 
 8             var del = del1   del2;
 9             del  = del3;    //使用  =
10             del("Hi!");
11 
12             Console.WriteLine("======分割线======");
13 
14             del -= del2;    //使用 -=
15             del("Hi!");
16 
17             Console.Read();
18         }

1 static void Main(string[] args) 2 { 3 var myClass = new MyClass(); 4 MyDel del1 = myClass.Print1; 5 MyDel del2 = myClass.Print2; 6 MyDel del3 = Print; 7 8 var del = del1 del2; 9 del = del3; //使用 = 10 //del("Hi!"); 11 12 var count = del.GetInvocationList().Length; //获取委托调用列表中方法的数量 13 Console.WriteLine(count); 14 15 Console.WriteLine("======分割线======"); 16 17 del -= del2; //使用 -= 18 //del("Hi!"); 19 20 count = del.GetInvocationList().Length; //获取委托调用列表中方法的数量 21 Console.WriteLine(count); 22 23 Console.Read(); 24 }

 


【参考】微软官方文档

] C# 知识回顾, C# 知识回顾 - 委托 delegate 【博主】反骨仔 【原文】 目录 What's 委托 委托的属性概述...

What's 委托

  delegate 一种自定义的引用类型,它包含了特定的参数列表和返回类型。

  使用委托时,只需要对应的方法的签名和返回类型兼容即可,无论是实例方法,抑或是静态方法。通过调用委托的实例就相当于调用方法本身,因为委托存储的是一个方法列表,调用委托的实例就相当于依次调用方法列表的内容。委托它将方法作为参数进行传递给了其它方法,我们常用的事件处理程序就是通过委托调用的方法,也是一种观察者模式的体现。

 

  下面的示例演示了一个委托声明:

public delegate int Del(int x, int y);

  

  使用委托的要求是:方法签名与返回类型兼容。可以是静态方法,也可以是实例方法。  

 

  【备注】方法的签名不包括返回值。

 

C# 知识回顾 - 委托 delegate

【博主】反骨仔    【原文】

C# 知识回顾 - 委托 delegate

【博主】反骨仔    【原文】

委托的属性概述

  • 类似于 C 和 C 中的函数指针,但它们是类型安全的。

  • 允许将方法作为参数进行传递。

  • 可用于定义回调方法。

  • 委托可以链接在一起;例如,可以对一个事件调用多个方法。

  • 方法不必与委托类型完全匹配。

 

本文由分分快三计划发布,转载请注明来源

关键词: