Если вам нравится создавать пользовательские делегаты, вы должны использовать ключевое слово delegate в нижнем регистре.
Что вы можете сделать с фактическим классом делегата? Для чего это полезно? Не понимаю точной разницы.
Если вам нравится создавать пользовательские делегаты, вы должны использовать ключевое слово delegate в нижнем регистре.
Что вы можете сделать с фактическим классом делегата? Для чего это полезно? Не понимаю точной разницы.
Из http://msdn.microsoft.com/en-us/library/system.delegate.aspx:
Класс
Delegate
- это базовый класс для типов делегатов. Однако только система и компиляторы могут явно из классаDelegate
или из классаMulticastDelegate
. Это также недопустимо выводить новый тип из типа делегата. КлассDelegate
не считается тип делегата; это класс, используемый для выводить типы делегатов.В большинстве языков реализовано
Delegate
ключевое слово и компиляторы для тех языки могут быть получены изMulticastDelegate
класс; следовательно, пользователи должны использовать ключевое словоDelegate
предоставляемый языком.
Ключевое слово delegate предназначено для компилятора, чтобы сделать для вас волшебство. Когда вы объявляете нового делегата с пользовательской подписью,
Итак, теперь, когда вы вызываете delObject(args)
- компилятор переводит это на delObject.Invoke(args)
Основной класс делегата предоставляет некоторые функции, такие как
Компилятор С# запрещает вам получать от делегата эксплицитно в вашем коде.. вам нужно использовать ключевое слово delegate.
Еще одна опрятная вещь, которую вы можете сделать с ключевым словом delegate
, - это создать делегаты inline, не объявляя их, например:
// constructor
public Form1()
{
this.Load += delegate(object sender, EventArgs e)
{
// Form1_Load code goes right here
}
}
Преимущество класса Delegate заключается в том, что он является базовым классом для всех типов делегатов в .Net. Наличие метода, который принимает экземпляр этого класса, позволяет вам работать в целом по всем типам делегатов. Вот почему такие операции, как ISynchronizedInvoke.Invoke, используют это как параметр.
Одна из вещей, которую может использовать класс 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();
}
}
}
С точки зрения реализации класс Delegate определяет поля, используемые для представления указателя функции делегата, а класс MultiCastDelegate предоставляет функциональность базовой линии, используемую событиями. Кроме того, как отмечали другие люди, Delegate предоставляет метод DynamicInvoke, который позволяет вам вызывать любой делегат.