Как создать новый тип делегата на основе существующего в С#?

Есть ли способ создать новый тип делегата на основе существующего? В моем случае я хотел бы создать делегат MyMouseEventDelegate, который будет иметь те же функции, что и EventHandler<MouseEventArgs>.

Зачем мне это нужно? Разумеется, использовать проверку типов времени компиляции! Таким образом, у меня могут быть два разных делегата: MyRightClickHandler и MyLeftClickHandler, и никогда два путаницы не будут смущены - даже если они оба функционально идентичны EventHandler<MouseEventArgs>.

Есть ли синтаксис для такого рода вещей?

О, и код вроде:

using MyRightClickHandler = EventHandler<MouseEventArgs>

недостаточно. Он не выполняет проверку типов, поскольку на самом деле он не создает новый тип. И мне пришлось бы вставить такую ​​строку в каждый файл кода, в котором я бы назвал MyRightClickHandler.

Ответы

Ответ 1

Ну, это так же просто, как копирование объявления делегата из оригинала. В С# ничего не делать, чтобы делать это автоматически, но я не вижу в этом большой нагрузки:

public delegate void MyLeftClickHandler(object sender, MouseEventArgs e);
public delegate void MyRightClickHandler(object sender, MouseEventArgs e);

Не похоже, что MouseEventHandler скоро изменится...

Неужели вы были укушены ошибками из-за неправильного использования неверных делегатов? Я не могу вспомнить, что когда-либо сам это обнаружил, и мне кажется, что вы вводите больше работы (и незнакомый набор делегатов для других разработчиков) - вы уверены, что это того стоит?

Ответ 2

Я хочу только выполнить проверку типа времени компиляции. Я думаю, этого достаточно, чтобы создать специализированные классы EventArgs для описанных вами случаев. Таким образом, вы все равно можете воспользоваться предопределенными делегатами:

class RightMouseButtonEventArgs : MouseEventArgs {}
class LeftMouseButtonEventArgs : MouseEventArgs {}

EventHandler<RightMouseButtonEventArgs>
EventHandler<LeftMouseButtonEventArgs>

Ответ 3

Нет. Согласно документации С#, типы делегатов запечатаны, и вы не можете создать новый тип делегирования, который наследуется от существующего.

Ответ 4

Я не верил jon-skeet. Я должен был попробовать это для себя. Он был прав.

public void F(object sender, MouseEventArgs e) {}; 
public MyLeftClickHandler l;
public MyRightClickHandler r;
public void Test()
{
    l = F;  // Automatically converted.
    r = F;  // Automatically converted to a different type.
    l = r;  // Syntax error.  Incompatible types.
    l = new MyLeftClickHandler(r);  // Explicit conversion works.
}

Это не было очевидно!