EventHandler со строго типизированным отправителем в C #

Меня раздражает то, что в событии по умолчанию Sender имеет тип object и поэтому почти всегда требует ручного приведения, прежде чем мы сможем его использовать. К счастью, поскольку VB теперь также поддерживает вариативность в делегатах, мы можем обновить подпись события таким образом, чтобы отправитель был строго типизирован, см. Параметр события; «отправитель как объект» или «отправитель как T»?

К сожалению, это не работает для существующих объявленных событий, отправители которых относятся к типу объекта.

Одним из решений, конечно же, было бы создание поддельного EventHandler, который внутренне позаботится о приведении типов за вас. Я сделал быстрый пример, см.:

struct EventHandler
    where TEventArgs: EventArgs
{
    private readonly Action _delegate;

    public EventHandler(Action @delegate)
    {
        if (@delegate == null)
            throw new ArgumentNullException("@delegate");

        _delegate = @delegate;
    }

    public static implicit operator EventHandler(EventHandler eventHandler)
    {
        return new EventHandler(eventHandler.Execute);
    }

    private void Execute(object sender, EventArgs e)
    {
        TSender typedSender = (TSender)sender;
        TEventArgs typedEventArgs = (TEventArgs)e;

        _delegate(typedSender, typedEventArgs);
    }
}

, который можно использовать так, как вы ожидаете от него:

class Program
{
    event EventHandler Test;

    static void Main(string[] args)
    {
        new Program().Main();
    }

    void Main()
    {
        Test += new EventHandler(TestEventHandler);

        Test(this, EventArgs.Empty);
    }

    void TestEventHandler(Program sender, EventArgs e)
    {
        throw new NotImplementedException();
    }
}

Теперь, если я действительно хочу использовать это, нужно проделать много работы. (Структура должна вести себя так же, как исходный делегат). Тем не менее, у меня есть ощущение, что либо уже существует отличная реализация, либо ее нет, поскольку есть некоторые серьезные недостатки, которые я упустил.

Кто может мне ответить на этот вопрос? Какие-нибудь другие подсказки?

6
задан Community 23 May 2017 в 12:14
поделиться