委托

委托是.net中的一个常见的概念,今天特意从头到尾研究了一下,本人不是高手,写出这篇文章的目的,只是希望可以帮一些刚接触.net的同仁。

文章章节

●委托的概念

●委托的应用

●委托的定义

●应用委托

●委托与事件

1、委托的概念

通过很多途径可以查找到很多关于委托的概念。虽然概念相同,但不同的人理解时又有所不同。我在理解时是将其理解为:委托是一个用于调用函数的对象。这一句话指明了委托是一个对象,这个对象不做别的事情,专门用来调用一些函数。直接这样说可能有点让人摸不着头脑,没关系,只要结合具体应用你就会理解。

2、委托的应用

首先,net中事件处理就是基于委托实现的,这也是为什么一提到委托就会扯到事件。委托的另一个用途就是用作回调方法。

3、委托的定义

委托是一个对象,在.net中定义一个委托时,要使用关键字delegate,如下面的代码

public delegate string JoinString(string FirstString,string SecondString) ;

这里需要说明,一个委托并不是能调用所有方法,在上面的定义中,我们看到了string FirstString与string SecondString两个参数,这两个参数就是“委托的签名”,与之对应的是方法的签名,也就是说,委托可以调用的方法,其方法的签名必须与委托的签名一致。针对上面我们定义的委托,下面的方法JoinName()是可以被调用的,而Splic()方法是不能被调用的。

签名相同,所以JoinString委托可以调用JoinName()方法

             public string JoinName(string one,string two)
             {
              //语句体;
             }

签名不相同,所以JoinString委托不可以调用Splic()方法

             public string Splic(string SplicString)
             {
              //语句体;
             }

下面是委托的调用

         public delegate string JoinString(string FristString,string SecondString) ;
  
         private void Page_Load(object sender, System.EventArgs e)
         {
          JoinString tJoinString = new JoinString( joinstring );//在实例化委托时将匹配的方法当作参函传给委托

          Response.Write( tJoinString("henry","yu") ) ;//调用委托
         }

         public string joinstring(string one,string two)
         {
          return one + "_" + two ;
         }

当然,上面的代码是完全没有用的。它只要告诉你委托怎么样声明、怎么样调用就可以了。下面将写一个有用的示例。

4、委托的应用

●将委托当作“回调”使用

我们将要写一个比较有意义的示例,这个示例是利用冒泡法对一个整型数组进行排序,具体的排序工作由委托完成。先来看一下用于排序的类。见下面的代码

public class SortDelegate
{
        public delegate bool SortOrder(int FirstNumber,int SecondNumber) ;//委托声明

        public SortDelegate()
        {
         //
         // TODO: 在此处添加构造函数逻辑
         //
        }

        public int [] Sort(int [] IntArray,SortOrder Order)
        {
         if ( Order == null || IntArray == null )
         {
          throw new ArgumentException() ;
         }

         int PositionMark = 1 ;

         bool Loop = false ;

         int Swap ;

         while ( Loop == false )
         {
          Loop = true ;

          for ( int i = 0 ; i < IntArray.Length - PositionMark ; i ++ )
          {
           if ( Order(IntArray[i],IntArray[i+1] ) == true )
           {
            Swap = IntArray[i] ;
      
            IntArray[i] = IntArray[i + 1] ;

            IntArray[i + 1] = Swap ;

            Loop = false ;
           }
          }

          PositionMark ++ ;
         }

         return IntArray ;
        }
}

SortDelegate类里声明了一个名为SortOrder委托,该委托在调用时需要两个int型的参数,并根据两个参数的大小返回一个bool值(排序的方式可以有委托调用的方法自己来定义)。

请注意Sort()方法的实现,Sort()方法需要两个参数,一个为要排序的数组,一个为SortOrder类型的委托。因为冒泡排序就是不断的判断并交换两个相邻位置上的数组元素,最后得出排序的数组。在判断两个相邻位置的数组元素是否需要交换位置时,利用的是委托。下面我们来使用SortDelegate类。

        private void Page_Load(object sender, System.EventArgs e)
        {
         int [] SortArray = new int[]{1,5,3,6,14,59,87,36,25,398,784,125,3695,2,11,4};

   SortDelegate TSortDelegate = new SortDelegate() ;

         SortDelegate.SortOrder TSortOrder = new SortDelegate.SortOrder( IsSwap ) ;

         Response.Write("排序前的数组为:" ) ;

         for ( int i = 0 ; i < SortArray.Length ; i ++ )
         {
          Response.Write(SortArray[i].ToString() + "," ) ;
         }

   TSortDelegate.Sort( SortArray , TSortOrder ) ;//调用Sort方法排序

         Response.Write("<br>排序后的数组为:" ) ;

         for ( int i = 0 ; i < SortArray.Length ; i ++ )
         {
          Response.Write(SortArray[i].ToString() + "," ) ;
         }
        }

        public bool IsSwap(int firstNumber,int secondNumber)
        {
         return firstNumber < secondNumber ;//在这里可以自定义排序的方式
        }

在将SortArray 数组的所有元素打印出之后,我们可以比较出排序前后的差别。下面我简单的分析一个上面的代码。首先声明一个int数组,并实例化一个SortDelegate类与SortOrder委托的实例,在实例化SortOrder委托的实例时,我们把IsSwap()方法当作参数传递过去。这个方法定义了排序的方式,在这里,我们是按从大到小的顺序来排列数组。之后调用SortDelegate类实例的Sort()方法,并把SortArray 与SortOrder委托实例当作参数传递过去,最后得到的数组就是排过序的数组。这种使用方法很类似于“回调”。

●组合委托形成链并代迭委托链

首先定义一个委托

public delegate int Command(int NumberOne , int NumberTow) ;

然后定义几个与这个委托签名相同的方法,这里我们分别定义了加、减、乘、除四个方法,如下代码

      public int JiaFa(int firstNumber,int secondNumber)
      {
       Response.Write("数字1为:" + firstNumber + " 数字2为:" + secondNumber + " 两数相加结果为" + (firstNumber + secondNumber) + "<br>" ) ;

       return firstNumber + secondNumber ;
      }

      public int JieFa(int firstNumber,int secondNumber)
      {
       Response.Write("数字1为:" + firstNumber + " 数字2为:" + secondNumber + " 两数相减结果为" + (firstNumber - secondNumber) + "<br>" ) ;
   
       return firstNumber - secondNumber ;
      }

      public int ChengFa(int firstNumber,int secondNumber)
      {
       Response.Write("数字1为:" + firstNumber + " 数字2为:" + secondNumber + " 两数相乘结果为" + (firstNumber * secondNumber) + "<br>" ) ;
  
       return firstNumber * secondNumber ;
      }

      public int ChuFa(int firstNumber,int secondNumber)
      {
       Response.Write("数字1为:" + firstNumber + " 数字2为:" + secondNumber + " 两数相除结果为" + firstNumber / secondNumber + "<br><br>" ) ;

       return firstNumber / secondNumber ;
      }

下的代码是关键

       Command TCommand = new Command( JiaFa ) ;

       TCommand += new Command(JieFa) ;

       TCommand += new Command(ChengFa) ;

       TCommand += new Command(ChuFa) ;

       //调用委托
       Response.Write("调用委托链<br>") ;

       TCommand( 40      , 20 ) ;

这样,TCommand 委托上一共有四个方法,这样就形成了一个链,当TCommand( 40      , 20 ) ;被执行时,这四个方法都会被执行。我们注意到,这四个方法都有一个返回值(本例的委托也是),那最后得到的返回是那个方法的返回值呢?四个方法有四个返回值,但委托只有一个,所以返回值也只有一个,尽管有四个方法,且最后的返回结果是委托链中最后一个方法所执行的结果。

当类似于这个的一个委托被执行时,如果链中的某个方法发生了异常会出现什么情况?也许你也猜到了,那就是从异常发生的地方开始,链中后面的方面都将不会被执行。所以如果你想找到该异常,或者想得到链中每个方法执行的返回值,那么可以手式迭代这个委托链,如下代码

       Response.Write( "手工代迭委托并执行<br>" ) ;

       Delegate [] Tdelegate = TCommand.GetInvocationList() ;

       object [] Para = new object[]{40,20};

       object Result ;

       foreach ( Delegate Tmpdelegate in Tdelegate )
       {
        Result = Tmpdelegate.DynamicInvoke( Para ) ;//获取结果

        if ( Result != null )
        {
         Response.Write( "单独执行,结果分别为" + ( (int)Result ).ToString() + "<br>" ) ;
        }
       }

5、事件与委托

今天从一本书上找到了一个关于事件的很好的例子,入在别一篇文章里。

《C#中的事件定义与处理》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值