博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 代理/委托 Delegate
阅读量:4983 次
发布时间:2019-06-12

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

本文转载自
1 . 委托的定义:
委托是函数的封装,它代表一 " 类 " 函数.
他们都符合一定的签名:拥有相同的参数列表,返回值类型.同时,委托也可以看成是对函数的抽象,是函数的 " 类 " .此时,委托的实例将代表一个具体的函数.
委托声明和定义了一个引用类型,它用来封装方法,用指定的签名来封装方法.一个委托的实例,可以封装静态或者实例方法.
委托是一种引用的类型,一旦为委托分配了方法,委托将与该方法完全相同的行为,委托方法的使用可以像其他任何方法一样, 具有参数和返回值
    委托的一个特征是它们的类型是安全的.可以确保被调用的方法签名是正确的,但他们并不关心调用该方法的是什么类型的对象,甚至不考虑该方法是静态方法还是实例方法.(给定委托的实例可以表示任何类型的任何对象上的实例方法或静态方法,只要方法的签名匹配于委托的签名就可以).
2 . 委托的使用:
    当要把方法传递给其他方法时,需要使用委托.
为什么什么用委托:
        更加灵活的方法调用.
        用于异步回调.
       多线程编程中使用委托来定启动一个线程时调用的方法.
       C#中的事件模型,用他们来指明处理给定事件的方法.
例:
class  Program
{
         // 定义委托
         delegate   double  ProcessDelegate( double  param1,  double  param2);
         static   double  Multiply( double  param1,  double  param2)
        {
             return  param1  *  param2;
        }
         static   double  Divide( double  param1,  double  param2)
        {
             return  param1  /  param2;
    }
         static   void  Main( string [] args)
        {
             // 定义委托变量
            ProcessDelegate pd;
             double  param1  =   20 ;
             double  param2  =   10 ;
            Console.WriteLine( " Enter M to multiply or D to divide " );
             string  input  =  Console.ReadLine();
             if  (input  ==   " M " )
            {
                 // 初始化委托变量,要把一个函数引用赋给委托变量,
                 // 参数是要使用的函数名,且不带括号.
                pd  =   new  ProcessDelegate(Multiply);
            }
             else
            {
                pd  =   new  ProcessDelegate(Divide);
            }
             // 使用该委托调用所选函数
            Console.WriteLine( " Result: {0} " ,pd(param1,param2));
            Console.ReadKey();
}
3 . 多播委托: 引用多个方法的委托,它连续调用每个方法.
为了把委托的单个实例合并为一个多播委托,委托必须是同类型的,返回类型必须是void,不能带输出参数out(可以带引用参数ref).
多播委托应用于事件模型中.
// 声明委托
     public   delegate   void  myDelegate();
     public   partial   class  Form1 : Form
    {
         public  Form1()
        {
            InitializeComponent();
        }
         public   void  aa()
        {
            Console.WriteLine( " aa " );
        }
         public   void  bb()
        {
            Console.WriteLine( " bb " );
        }
         public   void  cc()
        {
            Console.WriteLine( " cc " );
        }
        myDelegate md;
         private   void  button1_Click( object  sender, EventArgs e)
        {
            md  =   new  myDelegate(aa);
            md  +=   new  myDelegate(bb);
            myDelegate m  =   new  myDelegate(cc);
            md  +=  m ;
            md();
        }
    }
4 . 异步回调:
由于实例化委托是一个对象,所以可以将其作为参数进行传递.也可以将其赋值给属性.这样,方法便可以将一个委托作为参数来接受,并且以后可以调用该委托.这样称为异步回调,是在较长的进程完成后用来通知调用方的常用方法.以这种方式使用委托时,使用委托的代码无需了解有关所用方法的实现方面的任何信息.
回调的另一个常见用法是定义自定义的比较方法并将该委托传递给排序方法.
    例:
// 定义委托
     delegate   void  Del( int  a, int  b);
     class  Program
    {
         static   void  Main( string [] args)
        {
            Program p  =   new  Program();
            Del d  =   new  Del(p.F_min);    // 实例化委托并传给他比较的方法.
            p.CallBack( 10 ,  30 , d);    // 调用回调函数
        }
         // 回调函数,将委托实例作为方法参数进行传递.
    public   void  CallBack( int  a, int  b,Del d)
       {
           d(a, b);  // 执行委托
        }
        // 输出较大的数
         public   void  F_max( int  a,  int  b)
        {
            Console.WriteLine( " 大的那个数为:  "   +  Math.Max(a,b));       
        }
// 输出较小的数
      }
5 . 匿名方法
    匿名方法允许我们以一种”内联”的方式来编写方法代码,将代码直接与委托实例相关联,从而使得委托实例化的工作更加直观和方便.
使用例子:
class  Program{
     // 定义委托
     public   delegate   string  dTest( string  val);
     static   void  Main( string [] args){
         string  mid  =   " 男子足球队 " ;
         // 匿名方法
        dTest aDelegate  =   delegate ( string  param){
            param  +=  mid;
            param  +=   " 加油. " ;
             return  param;
        };
        Console.WriteLine(aDelegate( " 中国 " ));
        Console.ReadLine();
    }
}
如果委托类型的返回类型为void,匿名方法里便不能返回任何值.如果不为void,匿名方法里返回的值必须和委托类型的返回值兼容.
6 . 何时使用委托,何时接口 ?
   委托:
    当使用事件设计模式时.
    当封装静态方法可取时.
    当调用方不需要访问实现该方法的对象中的其他属性方法或接口时.
    需要方便的组合.
    当类可能需要该方法的多个实现时.
   接口:
    当存在一组可能被调用的相关方法时.
    当类只需要方法的单个实现时.
    当使用接口的类想要将该接口强制转换为其他接口或类类型时.
         public   void  F_min( int  a,  int  b)
        {
            Console.WriteLine( " 小的那个数为:  "   + Math.Min(a,b));
        }

转载于:https://www.cnblogs.com/abc8023/p/3620461.html

你可能感兴趣的文章
dorado中的creationType选择类型
查看>>
C++11 数值类型和字符串的相互转换
查看>>
无锡盈达聚力科技有限公司
查看>>
tyvj1659中中救援队
查看>>
kubernetes学习:CKA考试题
查看>>
LINUX samba的安装使用
查看>>
CSS border 生成三角
查看>>
asp.net(c#)开发中的文件上传组件uploadify的使用方法(带进度条)
查看>>
7.STM32中GPIO理解
查看>>
poj 1564
查看>>
asp.net 自己收集的面试题
查看>>
JAVA编程思想的理解
查看>>
base64 json
查看>>
在vim中搜索单词
查看>>
设置定点数学属性
查看>>
CSS3下的渐变文字效果实现
查看>>
###学习《C++ Primer》- 2
查看>>
js charAt()方法
查看>>
一些跨域问题
查看>>
配置RHEL&CentOS网络说明
查看>>