浅谈C#委托的用法-delegate[转]

一、委托的概念

  1. 委托和类一样是一种用户自定义类型,它存储的就是一系列具有相同签名和返回类型的方法的地址,调用委托的时候,它所包含的所有方法都会被执行。
  2. 借用百度上的一句话概括:委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,

    可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性

二、委托的声明

  与对应的方法具有相同的参数类型、参数个数、返回值。通俗来讲就是“函数的模板原型”。

三、委托的使用

  1. 用delegate声明一个委托
  2. 委托实例化
  3. 调用

     1 public class DelegateClass
     2     {
     3         public delegate void DelegateTest(int a, int b);  //1、声明一个委托
     4
     5         public static void Test()
     6         {
     7             DelegateTest method = new DelegateTest(Plus);   //2、实例化委托
     8             //DelegateTest method1 = Plus;  //实例化委托的另一种等价写法
     9             method.Invoke(1, 2);   //3、调用
    10             //method1(3, 4);   //调用的另一种等价写法
    11         }
    12
    13         private static void Plus(int a, int b)
    14         {
    15             Console.WriteLine("a={0} b={1}", a, b);
    16         }
    17     }

    四、委托的意义

      1、没有委托就没有异步

      2、解耦

      3、高效扩展

    1 public class CallStudent
     2     {
     3         //方法1
     4         public static void CallStudentA(string name)
     5         {
     6             Console.WriteLine("{0}", name);
     7         }
     8         //方法2
     9         public static void CallStudentB(string name)
    10         {
    11             Console.WriteLine("{0}", name);
    12         }
    13         //方法3
    14         public static void CallStudentC(string name)
    15         {
    16             Console.WriteLine("{0}", name);
    17         }
    18
    19         //传值的方式,根据值来决定行为,所有的方法全部耦合在一起,
    20         //如果要增加方法则需要修改该方法,不便于方法的封装、扩展
    21         public static void CallStudentName(string name, StudentType type)
    22         {
    23             if (type == StudentType.A)
    24             {
    25                 Console.WriteLine("{0}", name);
    26             }
    27             else if (type == StudentType.B)
    28             {
    29                 Console.WriteLine("{0}", name);
    30             }
    31             else if (type == StudentType.C)
    32             {
    33                 Console.WriteLine("{0}", name);
    34             }
    35         }
    36
    37         //用委托的方式来实现传递方法,如果要增加方法,只需要重新增加一个方法就好
    38         public static void CallStudentName(string name, CallStudentHandler handler)
    39         {
    40             handler.Invoke(name);
    41         }
    42     }
    43
    44     public delegate void CallStudentHandler(string name);
    45
    46     public enum StudentType
    47     {
    48         A,
    49         B,
    50         C
    51     }
    
    1 static void Main(string[] args)
     2         {
     3             //用不同的值来区分不同的方法
     4             CallStudent.CallStudentName("Student A",StudentType.A );
     5             CallStudent.CallStudentName("Student B", StudentType.B);
     6             CallStudent.CallStudentName("Student C", StudentType.C );
     7             Console.WriteLine();
     8
     9             //用委托的方式传递多个方法
    10             CallStudentHandler handlerA = new CallStudentHandler(CallStudent.CallStudentA);
    11             CallStudent.CallStudentName("Student A", handlerA);
    12
    13             CallStudentHandler handlerB = new CallStudentHandler(CallStudent.CallStudentB);
    14             CallStudent.CallStudentName("Student B", handlerB);
    15
    16             CallStudentHandler handlerC = new CallStudentHandler(CallStudent.CallStudentC);
    17             CallStudent.CallStudentName("Student C", handlerC);
    18             Console.WriteLine();
    19
    20             //用匿名函数的方法替代上述写法
    21             CallStudentHandler handler1 = new CallStudentHandler(
    22                 delegate(string name)
    23                 {
    24                     Console.WriteLine("{0}", name);
    25                 }); //用匿名的方式把方法名给去掉
    26             handler1.Invoke("Student A");
    27
    28             //用lambda表达式的方式1 替代上述写法
    29             //Lambda表达式的本质就是一个匿名方法
    30             CallStudentHandler handler2= new CallStudentHandler(
    31                 (string name)=>
    32                 {
    33                     Console.WriteLine("{0}", name);
    34                 }); //用lambda表达式的方式把delegate换成=>  箭头左边是参数列表,右边是方法体
    35             handler2.Invoke("Student A");
    36
    37             //用lambda表达式的方式2
    38             CallStudentHandler handler3 = new CallStudentHandler(
    39                 (name) =>
    40                 {
    41                     Console.WriteLine("{0}", name);
    42                 }); //去掉参数类型
    43             handler3.Invoke("Student A");
    44
    45             //用lambda表达式的方式3
    46             CallStudentHandler handler4 =(name) =>
    47                 {
    48                     Console.WriteLine("{0}", name);
    49                 }; //去掉 new CallStudentHandler
    50             handler4.Invoke("Student A");
    51
    52             //用lambda表达式的方式4
    53             CallStudentHandler handler5 = (name) => Console.WriteLine("{0}", name);   //去掉{},适用于方法体只有一行
    54             //去掉{}后,如果方法体只有一行,带返回值的去掉return
    55             handler5.Invoke("Student A");
    56
    57             Console.ReadLine();
    58         }

    参考:https://www.cnblogs.com/goldendragon/p/9922592.html

原文地址:https://www.cnblogs.com/lucode/p/12173994.html

时间: 2024-10-15 09:58:26

浅谈C#委托的用法-delegate[转]的相关文章

小兵 浅谈C#委托<delegate>

最近处于面试找工作的阶段,面试中遇到这个问题已经多次,一直想了解,就趁这个机会好好梳理一下啊. 当提及委托,大多数人第一印象是它相当于C++的函数指针,可以将方法作为参数进行传递,也可以达到函数回调的作用. 委托例子:其实在生活中也有很多这样的例子,例如我们打官司,首先应该找到律师,委托律师去帮我们打官司,这就是委托.在程序中我们可以针对这个例子这样写: 1.首先定义一个委托:public delegate void Lawyer(string matter)   //相当于律师这个角色 2.再

浅谈C#委托和事件(转载)

委托给了C#操作函数的灵活性,我们可使用委托像操作变量一样来操作函数,其实这个功能并不是C#的首创,早在C++时代就有函数指针这一说法,而在我看来委托就是C#的函数指针,首先先简要的介绍一下委托的基本知识: 委托的定义委托的声明原型是 delegate <函数返回类型> <委托名> (<函数参数>)例子:public delegate void CheckDelegate(int number);//定义了一个委托CheckDelegate,它可以注册返回void类型且

浅谈 C#委托

看了<CLR via C#>的17章委托后,为自己做一点浅显的总结,也分享给需要的人. .NET通过委托来提供一种回调函数机制,.NET委托提供了很多功能,例如确保回调方法是类型安全的(CLR重要目标).委托好允许顺序调用多个方法(委托链),并且支持调用静态方法和实例方法. 委托的基本语法就不多说了. internal delegate void Feedback(int value); public sealed class Program{ publick static void Main

浅谈C#委托

委托: 当要把方法传递给其他方法时,就需要使用委托.也就是把方法作为参数来传递. 委托是一种特殊的类型对象,其特殊在于我们定义的所有对象都包含数据,而委托包含的只是一个或多个方法的地址. 委托的一个特征是它们类型是安全的,可以确保调用的方法的签名是正确的.既可以调用对象的实例方法,也可以调用静态方法,只要方法的签名和委托的签名一致就行. 自定义委托: 示例: using System; namespace ConsoleApp { // 声明一个委托 参数double 返回值double del

浅谈awk的基本用法

awk 1.域和记录: 取第一域,并在开头和结尾加字符begin和end 通常使用BEGIN来显示变量和预置变量,使用END来输出最终结果. awk  ' BEGIN  {print "being"}  {print $1}  END  {print "end"}'   file 2.条件操作符: 第一字域,包含expect,就打印整行 awk '{if($1~/expect/) print $0}' c.sh 或者 awk '$1~/expect/{print $

【Python学习笔记之二】浅谈Python的yield用法

在上篇[Python学习笔记之一]Python关键字及其总结中我提到了yield,本篇文章我将会重点说明yield的用法 在介绍yield前有必要先说明下Python中的迭代器(iterator)和生成器(constructor). 一.迭代器(iterator) 在Python中,for循环可以用于Python中的任何类型,包括列表.元祖等等,实际上,for循环可用于任何“可迭代对象”,这其实就是迭代器 迭代器是一个实现了迭代器协议的对象,Python中的迭代器协议就是有next方法的对象会前

浅谈async函数await用法

今天状态不太好,睡久了懵一天. 以前只是了解过async函数,并还没有很熟练的运用过,所以先开个坑吧,以后再结合实际来更新下,可能说的有些问题希望大家指出. async和await相信大家应该不陌生,让异步处理变得更友好. 其实这玩意儿就是个Generator的语法糖,想深入学习得去看看Generator,不然你可能只停留在会用的阶段. 用法很简单,看代码吧. // 先声明一个函数,这个函数返回一个promise, 先记住哈!后面很多地方要用 function getPromise(str =

浅谈 css 之 position用法

在 css中, position 属性有四个值可用: static(默认值).absolute.relative.fixed. relative:相对定位(相对于自身进行在常规流中的位置进行定位,保留自身原始的位置) absolite: 1.相对于自身的包含块定位: 2.寻找包含块的规则:从自身网上寻找祖先元素,寻找到的第一个position为非static修饰的祖先元 素的内边距边界 就是当前绝对定位元素的包含块:如果没有的话,则相对于 html进行定位: 3.完全脱离文档流: 4.displ

浅谈java中bigInteger用法

1.赋值: BigInteger a=new BigInteger("1"); BigInteger b=BigInteger.valueOf(1); 2.运算: ① add(); 大整数相加 BigInteger a=new BigInteger("23"); BigInteger b=new BigInteger("34"); a. add(b); ②subtract(); 相减 ③multiply(); 相乘 ④divide(); 相除取整