Подтвердить что ты не робот

Ключевое слово Delegate vs. delegate

Если вам нравится создавать пользовательские делегаты, вы должны использовать ключевое слово delegate в нижнем регистре.

Что вы можете сделать с фактическим классом делегата? Для чего это полезно? Не понимаю точной разницы.

4b9b3361

Ответ 1

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

Класс Delegate - это базовый класс для типов делегатов. Однако только система и компиляторы могут явно из класса Delegate или из класса MulticastDelegate. Это также недопустимо выводить новый тип из типа делегата. Класс Delegate не считается тип делегата; это класс, используемый для выводить типы делегатов.

В большинстве языков реализовано Delegateключевое слово и компиляторы для тех языки могут быть получены из MulticastDelegate класс; следовательно, пользователи должны использовать ключевое слово Delegateпредоставляемый языком.

Ответ 2

Ключевое слово delegate предназначено для компилятора, чтобы сделать для вас волшебство. Когда вы объявляете нового делегата с пользовательской подписью,

  • компилятор создает новый тип для вас, полученный из MulticastDelegate (который, в свою очередь, происходит от делегата).
  • компилятор добавляет метод Invoke с вашей настраиваемой подписью
  • аналогичным образом компилятор добавляет методы BeginInvoke и EndInvoke для этого нового типа

Итак, теперь, когда вы вызываете delObject(args) - компилятор переводит это на delObject.Invoke(args)

Основной класс делегата предоставляет некоторые функции, такие как

  • CreateDelegate (для получения делегата, который переносит статический/экземплярный метод)
  • DynamicInvoke (для вызова делегата со списком аргументов - поздняя граница)
  • Объединение и удаление (для делегирования цепочки) объединение нескольких делегатов вместе, например, нескольких делегатов обработчика событий для события)

Компилятор С# запрещает вам получать от делегата эксплицитно в вашем коде.. вам нужно использовать ключевое слово delegate.

Ответ 3

Еще одна опрятная вещь, которую вы можете сделать с ключевым словом delegate, - это создать делегаты inline, не объявляя их, например:

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

Ответ 4

Преимущество класса Delegate заключается в том, что он является базовым классом для всех типов делегатов в .Net. Наличие метода, который принимает экземпляр этого класса, позволяет вам работать в целом по всем типам делегатов. Вот почему такие операции, как ISynchronizedInvoke.Invoke, используют это как параметр.

Ответ 5

Одна из вещей, которую может использовать класс 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();
        }
    }
}

Ответ 6

С точки зрения реализации класс Delegate определяет поля, используемые для представления указателя функции делегата, а класс MultiCastDelegate предоставляет функциональность базовой линии, используемую событиями. Кроме того, как отмечали другие люди, Delegate предоставляет метод DynamicInvoke, который позволяет вам вызывать любой делегат.