Delegate vs. delegate keyword

2019-01-21 16:47发布

问题:

If you like to create custom delegates you would use the delegate keyword in lowercase.

What can you do with the actual Delegate Class? What is this good for? I don't understand the exact difference.

回答1:

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

The Delegate class is the base class for delegate types. However, only the system and compilers can derive explicitly from the Delegate class or from the MulticastDelegate class. It is also not permissible to derive a new type from a delegate type. The Delegate class is not considered a delegate type; it is a class used to derive delegate types.

Most languages implement a delegate keyword, and compilers for those languages are able to derive from the MulticastDelegate class; therefore, users should use the delegate keyword provided by the language.



回答2:

The delegate keyword is for the compiler to do some magic for you. When you declare a new delegate with a custom signature,

  • the compiler creates a new Type for you derived from MulticastDelegate (which in turn derives from Delegate).
  • the compiler adds an Invoke method with your custom signature
  • similarly the compiler adds BeginInvoke and EndInvoke methods for this new type

So now when you call delObject(args) - the compiler translates that to delObject.Invoke(args)

The Delegate base class provides some functionality such as

  1. CreateDelegate (for obtaining a delegate wrapping a static/instance method)
  2. DynamicInvoke (to invoke a delegate with a list of arguments - late bound)
  3. Combine and Remove (for delegate chaining.. chain multiple delegates together e.g. multiple event handler delegates for an event)

The C# compiler forbids you from deriving from Delegate explcitly in your code.. you have to use the delegate keyword.



回答3:

Another neat thing you can do with delegate keyword is create delegates inline, without having to declare them, for example:

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


回答4:

The advantage of the Delegate class is that it is the base class for all delegate types in .Net. Having a method which takes an instance of this class allows you to operate generically over all manner of delegates. This is the reason operations like ISynchronizedInvoke.Invoke use this as a parameter.



回答5:

One of the things the Delegate class can be used for is more control when invoking event handlers. For example, with normal event processing, an exception in any event handler will prevent any later event handlers from being called. You can alter that behavior by using the Delegate class to manually invoke each event handler.

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


回答6:

From an implementation perspective, the Delegate class defines the fields used to represent a delegate's function pointer and the MultiCastDelegate class provides the base line functionality used by events. Also, as other people mentioned, Delegate provides the "DynamicInvoke" method which allows you to invoke any delegate.