http://tech.163.com/special/000915SN/LanguageC.html看看这个, 里面的委托讲的不错。

解决方案 »

  1.   

    class A
    {
        public void HelloA()
        {}
    }class B
    {
        public void HelloB()
        {}
    }
    _____________________________________________________如果在HelloB中调用A的HelloA怎么调用呢?class B
    {
        public void HelloB()
        {
            A a = new A();
            a.HelloA();
        }
    }..
    B b = new B();
    B.HelloB();
    这样带来一个后果,B类依托A类存在,这个叫"耦合"________________________________为了减少耦合可以使用以下办法class B
    {    pulic delagate void BDelagate();  //定义类型标准
        pulic BDelagate bDelagate;    public void HelloB()
        {
           if(bDelagate!= null)
           {
               bDelagate(); 
           }
        }
    }B b = new B();
    A a = new A();b.bDelagate= new BDelagate (a.HelloA);
    b.HelloB();这样A,B就不存在相互依赖的藕荷.______________________本质上就是一个对象中调用另外一个对象中函数的一种低耦合的办法.
    很类似接口.
    ____________添加Event 就可以成为事件,来限制介入函数的权限.
      

  2.   

    关于委托://一个很简单的例子
    using System;
    namespace AboutDelegate
    {
       public delegate double DemoDelegate(double m,double n);
       public class MyDelegate
         {
            public static void Main(string[] args)
             {
                 MyDelegate myobj=new MyDelegate();//实例化一个类对象,要调用非静态的函数
                   DemoDelegate aDelegate=new DemoDelegate(myobj.function1);//委托的语法
                   double i=aDelegate(3.25,6.45);
                 Console.WriteLine(i);
               }
            public double function1(double m,double n)
             {
                 return m*n;
             }
            public double function2(double m,double n)
             {
                 return m/n;
             }
         }
    }
                
            
      

  3.   

    多路委托的例子........
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;namespace Test
    {
        /*class Program
        {
            static void Main(string[] args)
            {
                MathOpt obj = new MathOpt();
                MathOptDelegate oppel;
                oppel = obj.Add;
                Console.WriteLine(oppel(1, 2));
                Console.Read();
            }
        }    class MathOpt
        {
            public int Add(int argument1, int argument2)
            {
                return argument1 + argument2;
            }
        }    public delegate int MathOptDelegate(int val1,int val2);*/    /*public delegate void ShowTime();
        class A
        {
            public void AShowTime()
            {
                Console.WriteLine("A:" + DateTime.Now);
            }
        }    class B
        {
            public void BShowTime()
            {
                Console.WriteLine("B:" + DateTime.Now);
            }
        }
        class Controller
        {
            private ShowTime d;
            public void RegisterDelegateForCallBack(ShowTime method)
            {
                d += method;
            }
            public void UnRegisterDelegateForCallback(ShowTime method)
            {
                d += method;
            }
            public void CallBack()
            {
                if (d != null)
                    d.Invoke();
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                A a = new A();
                B b=new B ();
                Controller c = new Controller();
                c.RegisterDelegateForCallBack(a.AShowTime);
                c.UnRegisterDelegateForCallback(b.BShowTime);
                Console.WriteLine("敲任意键继续,Escape退出......");
                while (Console.ReadKey(true).Key != ConsoleKey.Escape)
                {
                    c.CallBack();
                }
            }
        }*/   // public delegate void TimerCallback(Object state);
        class TaskInfo
        {
            public int count = 0;
        }
        class progeam
        {
            static void Main(string[] args)
            {
                TaskInfo ti = new TaskInfo();
                Timer t = new Timer(ShowTime, ti, 0, 1000);
                Console.ReadKey();
                t.Dispose();
            }
            static void ShowTime(Object ti)
            {
                TaskInfo t = ti as TaskInfo;
                t.count++;
                Console.WriteLine("{0},{1}", t.count, DateTime.Now);
            }
        }
    }
      

  4.   

      千万不要把委托当成类来看待,否则越想越糊涂。其实委托是一个变量,变量值是方法的名字。关于用途,比较有用的情况是:泛型类需要对泛型变量执行一个方法,例如根据泛型变量的内容返回某个固定类型的值。你可以传入一个参数,该参数是一个委托,委托里是所需的方法。using System;
    using System.Collections.Generic;
    using System.Text;namespace ConsoleApplication46
    {
        // 这里把GetNum<T>当做类看待,这句声明了一个类
        // delegate关键字作用和class关键字差不多
        delegate string GetStr<T>(T t);
        
        // 类 A 里不可以用类 T 的所有成员方法,所以要依靠额外传入的方法
        class A<T>
        {
            public string ToStr(T t, GetStr<T> method)
            {
                // return T.ToString(); // 无法用类 T 的所有成员方法
                return method(t);
            }
        }    class B
        {
            public string ToString(B b)
            {
                return "This is class B.";
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                string s;
                // 每次调用 ToStr 方法都传入合适的委托变量
                // 委托变量内的方法完成了泛型类做不到的任务.
                
                // 委托值为静态方法的名称
                int i = 2;
                GetStr<int> intMethod=new GetStr<int>(intToStr);
                s=new A<int>().ToStr(i,intMethod);
                Console.WriteLine(s);            // 委托值为动态方法的名称
                B b = new B();
                GetStr<B> BMethod = new GetStr<B>(b.ToString);
                s = new A<B>().ToStr(b, BMethod);
                Console.WriteLine(s);            // 委托值为匿名方法
                double Pi = 3.14;
                GetStr<double> doubleMethod = delegate(double d) { return d.ToString(); };
                s = new A<double>().ToStr(Pi, doubleMethod);
                Console.WriteLine(s);
                
                Console.Read();
            }
            static string intToStr(int i)
            {
                return i.ToString();
            }
        }
    }
      

  5.   

    [Quote=引用 9 楼 Q282898034 的回复:]
      千万不要把委托当成类来看待,否则越想越糊涂。其实委托是一个变量,变量值是方法的名字。关于用途,比较有用的情况是:泛型类需要对泛型变量执行一个方法,例如根据泛型变量的内容返回某个固定类型的值。你可以传入一个参数,该参数是一个委托,委托里是所需的方法。 
    ]委托是一种特殊的数据类型,和class是一个级别的
      

  6.   

    在asp.net里使用委托的主要目的是当希望定制一个事件,而又想省事不愿意写一个定制的Event类来接收定制的EventArgs, 这时可以声明一个委托来传递任意类型的参数,比如int, string等等。
      

  7.   

    前几天看到一个例子说是 speack  hello的问题(中国人和美国人)public static void UAS()
        {
            Console.WriteLine("Hello");
        }
        public static void China()
        {
            Console.WriteLine("你好");
        }
        public static void SpeackGo(Speak speak)
        {
            speak();
        }
        public delegate void Speak(); Speak sp = new Speak(UAS);
            SpeackGo(sp);
            sp = new Speak(China);
            SpeackGo(sp);这样就不需要switch case了来了一个英国人添加也很简单方便。
      

  8.   


            讲到委托,可能一些人对委托的概念还有些模糊。那么委托到底是什么呢?熟悉C或C++的朋友对函数指针应该相当清楚。C#里的委托与之就有同等功效,不过委托是面象对象的,类型安全的。简单的说,委托就是对方法的引用的一种手断。那么什么时候使用委托呢?有些情况下,我们需要在一个类中使用另一个类的方法。很多人能够想到的是,我在这个类中创建另一个类的一个实例,不就可以顺理成章的调用它的方法了么?事实上确实也是这样,但是。并非所有情况都可以这样做!!
            举个例子:我有一个主窗体(MainForm),由它创建并打开一个子窗体(SubForm)。我希望在子窗体上做某些操作的时候主窗体(MainForm)上的某些元素会发生变化。而这些变代并不要在等到关闭子窗体之后。比如,我希望在子窗体上双击某条数据,而该条数据就会自动被填写到主窗体的特定位置。想想这时候上叙的那种方法还会行得通吗?试都不会试,肯定是不行的。这时个委托就是最好的先择。可以在子窗体上定义一个委托,来指向主窗体上的一个方法。并在子窗体上双击了某条数据的时候执行这个委托。
          定义委托:以delegate关键字来定义委托,委托的签名跟方法的签名一样,有返回类型、委托名,参数。委托的实现在System.Delegate类中,所以。当定义了一个委托时,它自动从System.Delegate继承。也就是说:委托是只需要你定义就可以使用,而并不需要你去关心它的实现。下为委托定义示例:
    private delegate double MethodList(int _num1, int _num2);
    public delegate void MethodNull();
          从上面可以看出来,委托的签名与方法的签名一样,以什么样的签名形式定义委托,决定委托能接受哪种定义形式的方法。比如:上例中第一个委托能接受返回double类型,并且有两个int参数的方法。而第二个委托则接受不返回任何值,也没有任何参数的方法下面就以前面举的那个例子的需求来说演示一下委托的使用,要说明的是,我这里只演示关键的委托实现细节部分。并不将所有代码写出[我也没这样的精力(^_^)]。首先,我们看看在子窗体中的部份:
    ///比如我们定义CallMainFormMethod委托来执行主窗体上的方法
    public delegate void CallMainFormMethod(string _RsCode);
    public class SubForm : Form
    {
          public CallMainFormMethod ExeManFormMethod; //创建一个委托以执行方法
          public SubForm()
            {
                  InitializeComponent();
            }        ////这里是在dataGridView1上选中某行数据,并双击的时候执行委托。
            private void dataGridView1_DoubleClick(object sender, EventArgs e)
            {
                  if(this.dataGridView1.SelectedRows.Count > 0)
                  {
                        if(this.ExeManFormMethod != null) //这个主要防止在没有给委托传递方法时出错
                              this.ExeManFormMethod(this.dataGridView1.SelectedRows[0].Cells["DataCode"].Value.ToString());
                  }
            }
    }好现在来看看在主窗体MainForm中创建并打开子窗体(SubForm)时的代码:
    public class MainForm : Form
    {
          private SubForm __SubForm;      public MainForm()
          {
                InitializeComponent();
          }    private void AddData(string _dataCode)
        {
                ////此方法执行将数据录入到主窗体的特定位置
        }      ////创建并打开子窗体的事件
          private void mentItem1_Click(object sender, EventArgs e)
          {
                  if(this.__SubForm != null && !this.__SubForm.IsDisposed)
                        this.__SubForm.Dispose();
                  this.__SubForm = new SubForm();
                  this.__SubForm. ExeManFormMethod = new CallMainFormMethod(this.AddData);
                  this.__SubForm.Show();
          }
    }
    好了,实现前面所说例子的功能的原理大概就是这样。希望各位不要偷懒,详细理解这个演示所彩用的实现原理。然后自己写代码来实践一番。当然,委托的运用是很广泛的。我这里只是举了个及典型的例子,希望能给对委托概念尚不是很清淅的朋友一点线索。更多的运用还得各位自己在日后开发中跟据自己的理解自行变通。多播委托:
          也可以叫它多路委托,委托是一个可以接受与其签名形式相符的方法引用的列表。我们可以用一个委托指向多个方法,只要这些方法都位于同一个应用程序域,就不需要管它来自何处。多播委托是一次性执行多个方法非常有效并且简洁的手断。比如:我做在一个窗体上作操作,所希这个操作能响影已有的几个窗体,下在说明如何给委托添加多个方法和移除委托中已有的方法:
    以前面代码为基:////向委托添加多个方法
    this.__SubForm. ExeManFormMethod += new CallMainFormMethod(this.AddData);
    this.__SubForm. ExeManFormMethod += new CallMainFormMethod(this.InsertData);////向委托中移除方法
    this.__SubForm. ExeManFormMethod -= new CallMainFormMethod(this.AddData);
    this.__SubForm. ExeManFormMethod -= new CallMainFormMethod(this.InsertData);