委托实例两则

实例一
       委托包含对 方法(不是方法名)的引用。使用委托可以在运行时决定调用哪个方法,甚至可以不用知道方法名就可以调用方法(因为我们是使用委托的对象来进行执行方法),执行(或调用)委托实际上将执行该委托所引用的方法。

       委托将一个委托对象与所指定的方法联系起来,该方法的实现就可以与该委托对象联系起来,这样该委托对象就可以调用那个特定的方法。但是,委托要求方法和委托的定义具有相同的方法签名(即两者都要接受相同个数和类型的参数),并返回相同类型的参数。

       注:被委托的方法的返回类型和参数列表相同(即参数类型和个数必须相同);委托有点类似于带参数的类声明,可以声明委托的对象,并用被委托的方法作为参数实例化这个对象。

       可以把委托看作一个通用的方法名,该名称可以在不同的时刻指向不同的方法,并且可以通过该委托执行这些方法。

 

例子:

 

using System;

 

namespace delegate_test

{

     class TestDelegates

     {

         // 定义委托

         public delegate int dgtCallFun(int param1,int param2);

 

         class MathsOperations

         {

              // 方法的定义,注意与委托定义的参数列表相同

              public int addFun(int a,int b)

              {

                   return a+b;

              }

              //

              public int MulFun(int a,int b)

              {

                   return a*b;

              }

         }

 

         class test

         {

              /// <summary>

              /// 应用程序的主入口点。

              /// </summary>

              [STAThread]

              static void Main(string[] args)

              {

                   //声明一个委托的对象

                   dgtCallFun dgtObj;

                   MathsOperations maths= new MathsOperations();

 

                   // 用maths对象的addFun方法作为参数来实例化委托对象。

                   // addFun方法的定义与委托的定义参数相同

                   dgtObj = new dgtCallFun(maths.addFun);

                  

                   // 调用委托,也即是执行被委托的方法

                   int b = dgtObj(5,6);

                   System.Console.WriteLine("方法addFun委托后执行的结果是:{0}",b);

                   // 改变委托对象所指向的方法

                   dgtObj = new dgtCallFun(maths.MulFun);

 

                   // 再次调用委托,注意与前一次调用方式完全一致。

                   b = dgtObj(5,6);

                   System.Console.WriteLine("方法MulFun委托后执行的结果是:{0}",b);

                   System.Console.Read();

              }

         }

     }

}

 

/*输出结果是如下:

 方法addFun委托后执行的结果是:11

 方法MulFun委托后执行的结果是:30

 */

 

实例二
一个函数带有参数非常平常,但一个类带有一个方法的参数可能会觉得奇怪,这就是委托的特征。很多书籍都说委托就象C或C++的函数指针,说得不无道理,因为它允许在委托对象的内部封装方法的引用,也就是前面所说的带有一个方法的参数,这个方法参数有一定的规则,它可以是静态的,也可以是一个实例方法,这个方法的参数和返回类型必须和委托对象所带的相同。 
         委托就像一个中间代理,通过引用这个委托对象,就可以调用被这个委托对象所引用的方法,也就是它所带的方法参数。可以调用它引用的方法,而不用管这个方法的哪个类的,因为已经通过这个委托对象去引用这个类的方法了,即我们调用这个方法是通过这个委托中间代理来实现的。有一点好处就是委托它是面向对象的,而且类型安全的。看以下代码:
class 委托人
{
 public string invokedmethod()  //注意此方法返回string,与委托对象相同,所要委托的事
 {
  Console.WriteLine("Hello"); 
 }
}

class  类
{
委托人 classobj = new 委托人();
delegate string 被委托人();  //声明一个返回类型为string的委托对象
被委托人 deleobj=new 被委托人(classobj.invokedmethod);//创建一个带有方法的委托对象
deleobj();  //调用classobj.invokedmethod方法
}

        委托通常与事件一起结合使用。事件是对用户动作的处理,当用户有某种动作的时候,通过委托对象来执行,因此,事件是通过委托来声明的。事件可以使用任何类型的委托,但有一点要注意,就是在使用组件时要遵循一些规则:事件使用的委托类型应有两个参数,一个是对象源,一个是e参数。对象源表示事件发生的源 ; e表示封装该事件的一些信息,这个e是从EventArgs类派生出来的。事件处理程序其实就同系统已定义的按钮点击事件,只不过这一次是由我们自己来定义而已。

//********************************************/
/**//*       Delegate Sample
/* 
//*****************************************************************
*/


using System;

namespace EventTest
{
 
//事件类
 public class EventClass
 
{
  
public void display(object sender,System.EventArgs e)
  
{
   Console.WriteLine(
"This is the Event Class");
   Console.ReadLine();
  }

 }

 
//调用类
 class InvokeClass
 
{
  
//声明代理对象,注意参数
   public delegate void delegateobj(object sender,System.EventArgs e);
  
//声明事件对象 
  private event delegateobj obj;
  
//声明要调用的事件类对象
  private EventClass ec;
  
  
public InvokeClass()
  
{
   ec
=new EventClass();
   
//添加事件对象到事件队列中,参数为要调用的事件
   this.obj+=new delegateobj(ec.display);
  }

  
//调用delegate对象触发事件
  protected void OnObj(System.EventArgs e)
  
{
   
if(this.obj!=null)
   
{
     obj(
this,e);
   }

  }

  
public void RaiseEvent()
  
{
   EventArgs e
=new EventArgs();
   OnObj(e);
  }

  
static void Main(string[] args)
  
{
   InvokeClass ic
=new InvokeClass();
   Console.WriteLine(
"Please input a string");
   
string input=Console.ReadLine();
   
if(input.Equals(""))
   
{
    Console.WriteLine(
"Sorry,you don't input anything");
   }

   
else
   
{
    
//触发事件
    ic.RaiseEvent();
   }

  }

 }

}

posted @ 2009-03-19 15:55  YaSin  阅读(370)  评论(0)    收藏  举报