近日一直在关注如何使用委托,但是使用方法到是好理解,但是如何应用的恰到好处却一直困扰着我。下面是在网上看到的一个例子,希望已经对委托理解很好的人帮忙指点一下。
using System; class MathClass
{
public static int max(int a,int b)
{return(a>b?a:b);} public static int min(int a,int b)
{return(a-b);} public static int sub(int a,int b)
{return (a+b);} public static int minus(int a,int b)
{return (a-b);}
}class Handler
{
private delegate int Calculation(int a, int b);
private static Calculation[] myCalculation=new Calculation[3];
public static void EventHandler(int i,int a,int b)
{
switch (i)
{
case 1:
myCalculation[0]=new Calculation(MathClass.max);
myCalculation[1]=new Calculation(MathClass.min);
Console.WriteLine(myCalculation[0](a,b));
Console.WriteLine(myCalculation[1](a,b));
break;
case 2: 
myCalculation[0]=new Calculation(MathClass.sub);
myCalculation[1]=new Calculation(MathClass.minus);
Console.WriteLine(myCalculation[0](a,b));
Console.WriteLine(myCalculation[1](a,b));
break;
default:
return;
}
}
}class Test
{
static void Main()
{
Handler.EventHandler(1,10,3);
Handler.EventHandler(2,10,3);
}
}
上面的例子我用 SELECT-CASE 我感觉会更容易实现或理解。如果想让调用者更加明确,我可以在声明一个enum,为什么还用这么麻烦的委托呢? 可能我对委托的理解还有些偏差,请高手赐教,谢。

解决方案 »

  1.   

    委托通常的用法是:
    系统类(或者已提供的公共类)提供一种委托类型,且在某个方法中当作参数传给自己调用,这个参数供应用开发程序员去提供。
    这样系统类就是在调用一个只知道签名而没有实现的方法,这个实现过程就可以由你(应用开发程序员)来决定。
    这当然就不是case可以相提并论的了。确参考一下回调(异步回调),事件,和线程吧。
      

  2.   

    http://zeus.cnblogs.com/archive/2005/12/12/295656.html
      

  3.   

    结合最近一次用委托,谈谈什么时候该用委托因为要做数据库插入操作,为了保持数据的完整性,难免要用到事务,但是使用数据库本身的事务操作,缺少点灵活性,于是就想到了Com+的事务。Com+事务需要生成的类继承自ServicedComponent 接口,然后还有一推的属性加上去,但常常我一个类可能只有一个方法需要使用事务,而且这个方法的参数也比较固定,就是两个DataSet,这个时候我就想到了委托。建立一个这样的类。[Transaction(System.EnterpriseServices.TransactionOption.Required)]
    [ClassInterface(ClassInterfaceType.AutoDispatch)] 
    [ObjectPooling(MinPoolSize=4, MaxPoolSize=4)] 
    [EventTrackingEnabled] public class MyComPlus:ServicedComponent
    {
           public delegate void TranSactionProcess(DataSet arg1,DataSet arg2);
           public TranSactionProcess Process;

    public MyComPlus()
    {
    //
    // TODO: 在此处添加构造函数逻辑
    //
    }
    protected override bool CanBePooled() 
    {
    return true; 
    }
    [AutoComplete]
    public void RunTranSaction(DataSet arg1,DataSet arg2)
    {
    return Process(arg1,arg2);
    }
    }里面的RunTranSaction函数就是使用事务的函数。这样我在自己的类中如果要使用事务的话就可以使用这个代理了public class MyClass
    {
    ....
    //下面的方法需要用到事务
    public void  TransInsertPoData( DataSet ds1,DataSet ds2)
    {                MyDataAccess  dal=new MyDataAccess();  
            try
            {      
               dal.Update(ds1);
               dal.Update(ds2);
            }
            }
    //使用下面的方法来实现事务
        public InsertPoData( DataSet ds1,DataSet ds2)
    {
    MyComPlus complus=new EleadComPlus();
        complus.Process+=new MyComPlus.TranSactionProcess(TransInsertPoData);
    rcomplus.RunTranSaction(ds1,ds2);
    }
    }
      

  4.   

    有许多人问的,.Net中的委托以及事件处理。我拿简单的例子说明一下,是现实中的例子:比如说一个公司(场景),你是老板,手下有两个员工,小张和小王。
    你命令小王,如果小张玩游戏,则小王扣去小张500元钱。这就是现实中的委托。实际上,在写程序中,程序员就是老板,小张和小王就是两个对象。小张玩游戏是一个方法,小张还有一个游戏事件,他玩游戏激发这个事件。而小王就是事件处理对象,他负责把小张的钱扣除500。所以,委托有如下几个要素:
    1 激发事件的对象--就是小张
    2 处理对象事件的对象--就是小王
    3 定义委托,就是你让小王监视小张。如果这三个要素都满足的话,则你就写出了一个完整事件的处理。下面有个例子:在vs.net2003 C#控制台应用程序编辑运行成功:
    using System;namespace CSharpConsole
    {
        public class 场景
        {
            [STAThread]
            public static void Main(string[] args)
            {
     Console.WriteLine("场景开始了....");
     // 生成小王
     小王 w = new 小王();
     // 生成小账
     小张 z = new 小张(); // 指定监视
     z.PlayGame += new PlayGameHandler(w.扣钱);
       
     // 开始玩游戏
     z.玩游戏(); Console.WriteLine("场景结束...");
     Console.ReadLine();
             }
        }
        // 负责扣钱的人
        public class 小王
        {
     public 小王()
     {
                  Console.WriteLine("生成小王...");
     } public void 扣钱(object sender,EventArgs e)
     {
      Console.WriteLine("小王:好小子,上班时间胆敢玩游戏...");
      Console.WriteLine("小王:看看你小子有多少钱...");
      小张 f = (小张)sender;
      Console.WriteLine("小张的钱: " + f.钱.ToString());
      Console.WriteLine("开始扣钱......");
      System.Threading.Thread.Sleep(500);
      f.钱 = f.钱 - 500;
      Console.WriteLine("扣完了....现在小张还剩下:" + f.钱.ToString());
     }
        }    // 如果玩游戏,则引发事件
        public class 小张
        {
     // 先定义一个事件,这个事件表示“小张”在玩游戏。
             public event PlayGameHandler PlayGame;
     // 保存小张钱的变量
     private int m_Money; public 小张()
     {
      Console.WriteLine("生成小张....");
      m_Money = 1000; // 构造函数,初始化小张的钱。
     } public int 钱 // 此属性可以操作小张的钱。
     {
      get
      {
       return m_Money;
      }
      set
      {
       m_Money = value;
      }
     } public void 玩游戏()
     {
      Console.WriteLine("小张开始玩游戏了.....");
      Console.WriteLine("小张:CS好玩,哈哈哈! 我玩.....");
      System.Threading.Thread.Sleep(500);
      System.EventArgs e = new EventArgs();
      OnPlayGame(e);
     } protected virtual void OnPlayGame(EventArgs e)
     {
      if(PlayGame != null)
      {
       PlayGame(this,e);
      }
     }
        }    // 定义委托处理程序
        public delegate void PlayGameHandler(object sender,System.EventArgs e);}
    ====ww.madeinwuxi.com====
    http://www.madeinwuxi.com
      

  5.   

    又见玩游戏被扣工资的例子…………建议看看我的解释,我觉得扣工资例子做得很不好。http://community.csdn.net/Expert/topic/4455/4455220.xml?temp=.8347284 -- 扣工资例子、委托与事件处理初步知识http://community.csdn.net/Expert/topic/4465/4465328.xml?temp=.6670038 -- 回调函数、委托的应用机会等的讨论
      

  6.   

    委托常用于功能组合。
    一个常见的运用就是窗体的关闭,但往往只关闭窗体是不能满足要求的。
    在很多情况下关闭窗体前需要做什么,关闭后又需要做什么。
    所以在winform下关闭窗体前后分别会触发closing,closed两个事件。
    通过这种方法能够更好地把功能组合起来。
    对于COM+的那个例提一个小意见,代码如下
    [AutoComplete]
    public void RunTranSaction(parans IDataAccess[] access)
    {
    if(access !=null && access.length >0)
                                foreach(IDataAccess item in access)
                                      item.Execute();
    }通过接口分离可以让功能更灵活。
      

  7.   

    [回复人: SHOWMSDN() ( ) 信誉:100  2005-12-20 21:14:00  得分: 0  
     
    或者能给一个更清晰明了的例子(也就是这个例子不是很复杂,但是不用委托就不行,或者用委托以后要比不用有明显的优势) ]
    那我把 http://community.csdn.net/Expert/topic/4465/4465328.xml?temp=.6670038 这里的回复重新发一遍好了……外加一点修正。
     
    ------------------例如有一个方法,它的作用是从来源A获取信息然后发布到目标B,但是它不会处理信息。它的工作是这个样子的:while (还没下班) {
      // 获取信息
      // 获取信息
      // 获取信息
      // 获取信息   // 处理信息——我不知该怎么处理  // 发布信息
      // 发布信息
      // 发布信息
      // 发布信息 
    }它就可以将处理信息那里抽象成一个委托,这个委托的输入是获取回来的信息,输出是经过处理可以发布的信息:
    public delegate string/*输出*/ ProcessInfoDelegate(string rawMessage)/*输入*/这样,方法就可以写成public void TransferInfo(A source, ProcessInfoDelegate how, B destination)
    {
      while (!TimeToGoHome()) {
        string msg;
        // ...
        // 获取信息中
        // ...    if (how != null) // 如果别人提供了信息处理方法
          msg = how(msg); // 就委托别人做信息处理工作    // ...
        // 发布信息中
        // ...
      }
    }那么,如果有一个类需要用这个方便的方法,它就先定义它期待的信息处理方法,例如
    class User
    {
      private string MyProcessor(string input)
      {
         return input.Substring(2); // 不要最前面两个字符
      }然后调用方法:
      public void Do()
      {
         ....
         ClassName.TransferInfo(src,
           new ProcessInfoDelegate(MyProcessor), // 包装委托变量
           dest);
      }
    }
      

  8.   

    http://blog.csdn.net/julong88/archive/2005/09/22/487316.aspx
      

  9.   

    告诉你一个最简单的例子:c#中的线程。当你新增一个线程时,线程初始化需要一个ThreadStart,ThreadStart就是一个委托。为什么?因为线程运行时要执行方法。这个方法肯定是你自己定义的一个方法。
    ThreadStart委托就可以包装你的方法,传递给线程。让线程来执行。所以委托就是“方法引用”
      

  10.   

    如果方法相当于一个动词,委托相当于一个动名词
    class 人类
    {
        //构造函数代码略
        public void 好()
    }
    //分别new 一个人类的实例:我、他 (代码略 )public void delegate 好(); 好 他好=new 好(他.好)
    好 我好=new 好(我.好)
    好 大家好=他好+我好嘿嘿,汇仁肾保:)
      

  11.   

    玩游戏扣钱扣的汇仁肾保都出来了委托明天见,委托天天见(.NET事件模型)