Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net Delegate与Delegate关键字_.net_Delegates - Fatal编程技术网

.net Delegate与Delegate关键字

.net Delegate与Delegate关键字,.net,delegates,.net,Delegates,如果要创建自定义委托,可以使用小写的delegate关键字 对于实际的委托类,您可以做什么?这有什么用?我不明白确切的区别。委托类的优点是它是.Net中所有委托类型的基类。拥有一个获取此类实例的方法允许您对所有类型的委托进行常规操作。这就是ISynchronizedInvoke等操作将其用作参数的原因。来自: 委托类是基类 对于委托类型。然而,只有 系统和编译器可以派生 明确地从委托类或 从多播委托类。信息技术 也不允许导出 从委托类型创建新类型。这个 委托类不被视为 委托类型;这是一个用来 派

如果要创建自定义委托,可以使用小写的
delegate
关键字


对于实际的
委托
类,您可以做什么?这有什么用?我不明白确切的区别。

委托类的优点是它是.Net中所有委托类型的基类。拥有一个获取此类实例的方法允许您对所有类型的委托进行常规操作。这就是ISynchronizedInvoke等操作将其用作参数的原因。

来自:

委托
类是基类 对于委托类型。然而,只有 系统和编译器可以派生 明确地从
委托
类或 从
多播委托
类。信息技术 也不允许导出 从委托类型创建新类型。这个
委托
类不被视为 委托类型;这是一个用来 派生委托类型

大多数语言实现一个
委托
关键字,以及这些关键字的编译器 语言能够从
多播代理
类;所以,, 用户应使用
delegate
关键字 由语言提供


delegate关键字是为了让编译器为您发挥一些魔力。使用自定义签名声明新委托时

  • 编译器为您创建一个从MulticastDelegate派生的新类型(MulticastDelegate又从Delegate派生)
  • 编译器将添加一个带有自定义签名的Invoke方法
  • 类似地,编译器为这种新类型添加了BeginInvoke和EndInvoke方法
因此,现在当您调用
delObject(args)
-编译器将其转换为
delObject.Invoke(args)

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

  • CreateDelegate(用于获取包装静态/实例方法的委托)
  • DynamicInvoke(使用参数列表调用委托-后期绑定)
  • 合并并删除(用于委托链接..将多个委托链接在一起,例如,一个事件的多个事件处理程序委托)

  • C#编译器禁止您在代码中明确地从委托派生。。您必须使用delegate关键字

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

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

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

    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();
            }
        }
    }
    

    但是,应该注意的是,以这种方式调用委托是后期绑定的,并且(相应地)较慢。+1:特别要提到的是,“编译器将为您创建一个从MulticastDelegate派生的新类型”。因此,默认情况下,我们创建的委托都是多播委托
    编译器会为您创建一个新类型,该类型派生自MulticastDelegate
    ,对此我不确定。但是,根据
    的规定,只有系统和编译器可以显式地从委托类或多播委托类派生。
    请注意关键字“or”