委托与委托关键字

时间:2009-04-22 20:21:05

标签: .net delegates

如果您想创建自定义代理,请使用小写的delegate关键字。

您可以对实际的Delegate班级做些什么?这有什么用?我不明白确切的区别。

6 个答案:

答案 0 :(得分:37)

委托关键字是让编译器为你做一些魔术。当您使用自定义签名声明新委托时,

  • 编译器为您创建一个从MulticastDelegate派生的新类型(然后从Delegate派生)。
  • 编译器使用您的自定义签名
  • 添加Invoke方法
  • 同样,编译器为这个新类型添加了BeginInvoke和EndInvoke方法

现在,当您致电delObject(args)时,编译器会将其转换为delObject.Invoke(args)

Delegate基类提供了一些功能,例如

  1. CreateDelegate(用于获取包装静态/实例方法的委托)
  2. DynamicInvoke(用于调用带有参数列表的委托 - 后期绑定)
  3. 组合和删除(用于委托链接..将多个代理链接在一起,例如事件的多个事件处理程序委托)
  4. C#编译器禁止您在代码中明确地从Delegate派生..您必须使用delegate关键字。

答案 1 :(得分:34)

来自http://msdn.microsoft.com/en-us/library/system.delegate.aspx

  

Delegate类是基类   代表类型。但是,只有   系统和编译器可以派生出来   显式来自Delegate类或   来自MulticastDelegate课程。它   也不允许推导出一个   委托类型的新类型。该   Delegate类不被视为a   代表类型;它是一个习惯的类   派生委托类型。

     

大多数语言实现delegate   关键字,以及那些的编译器   语言能够从中衍生出来   MulticastDelegate班;因此,   用户应使用delegate关键字   由语言提供。

答案 2 :(得分:3)

使用delegate关键字可以做的另一个巧妙的事情是创建委托内联,而不必声明它们,例如:

// constructor
public Form1()
{
    this.Load += delegate(object sender, EventArgs e)
    {
         // Form1_Load code goes right here
    }
}

答案 3 :(得分:2)

Delegate类的优点是它是.Net中所有委托类型的基类。拥有一个获取此类实例的方法允许您通过所有方式的代理进行操作。这就是ISynchronizedInvoke.Invoke之类的操作将此作为参数使用的原因。

答案 4 :(得分:2)

调用事件处理程序时,Delegate类可以使用的一个功能是更多控件。例如,对于正常事件处理,任何事件处理程序中的异常都将阻止调用任何后续事件处理程序。您可以使用Delegate类手动调用每个事件处理程序来更改该行为。

using System;

namespace DelegateClass
{
    class EventSource
    {
        public event EventHandler TheEvent;

        internal void RaiseEvent1()
        {
            EventHandler handler = TheEvent;
            if (handler != null)
                handler(this, EventArgs.Empty);
        }

        internal void RaiseEvent2()
        {
            EventHandler handler = TheEvent;
            if (handler == null)
                return;

            Delegate[] handlers = handler.GetInvocationList();
            foreach (Delegate d in handlers)
            {
                object[] args = new object[] { this, EventArgs.Empty };
                try
                {
                    d.DynamicInvoke(args);
                }
                catch (Exception ex)
                {
                    while (ex.InnerException != null)
                        ex = ex.InnerException;

                    Console.WriteLine(ex.Message);
                }
            }
        }
    }

    class Program
    {
        static void Handler1(object sender, EventArgs e)
        {
            Console.WriteLine("Handler1");
        }

        static void Handler2(object sender, EventArgs e)
        {
            Console.WriteLine("Handler2");
            throw new InvalidOperationException();
        }

        static void Handler3(object sender, EventArgs e)
        {
            Console.WriteLine("Handler3");
        }

        static void Main(string[] args)
        {
            EventSource source = new EventSource();
            source.TheEvent += Handler1;
            source.TheEvent += Handler2;
            source.TheEvent += Handler3;

            try
            {
                source.RaiseEvent1();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.WriteLine("-------------------");

            source.RaiseEvent2();
        }
    }
}

答案 5 :(得分:1)

从实现角度来看,Delegate类定义用于表示委托函数指针的字段,MultiCastDelegate类提供事件使用的基线功能。另外,正如其他人提到的,Delegate提供了“DynamicInvoke”方法,允许您调用任何委托。