编写一个接收两种不同类型的EventHandler的方法

时间:2014-05-05 15:36:43

标签: c# event-handling overloading

我已经编写了这些扩展方法,我想将它们压缩成一个,因为它们有效地完成了同样的事情。我遇到的问题是我无法将HtmlElementEventHandler作为EventHandler参数传入。

    public static async Task WaitUntilAsync
        (this Action action, Action<EventHandler> addHandler,
        Action<EventHandler> removeHandler, Predicate<string> pred)
    {
        var t = new TaskCompletionSource<bool>();

        System.EventHandler handler = new System.EventHandler((s, e) => 
            {
                if (pred((s as MyAsyncWebBrowser).DocumentTitle))
                    t.SetResult(true);
            });

        addHandler(handler);

        action();
        await t.Task;

        removeHandler(handler);
    }

    public static async Task WaitUntilAsync
(this Action action, Action<System.Windows.Forms.HtmlElementEventHandler> addHandler,
Action<System.Windows.Forms.HtmlElementEventHandler> removeHandler, Predicate<string> = h => true)
    {
        var t = new TaskCompletionSource<bool>();

        System.Windows.Forms.HtmlElementEventHandler handler = new System.Windows.Forms.HtmlElementEventHandler((s, e) =>
        {
            if (pred)
                t.TrySetResult(true);
        });

        addHandler(handler);

        action();
        await t.Task;

        removeHandler(handler);
    }

有什么想法吗?

以前的尝试

    public static async Task WaitUntilAsync<TDelegate>
        (this Action action, Action<TDelegate> addHandler,
        Action<TDelegate> removeHandler, Predicate<string> pred)
    {
        var t = new TaskCompletionSource<bool>();

        TDelegate handler = (s, e) =>
        {
            if (pred((s as MyAsyncWebBrowser).DocumentTitle))
                t.SetResult(true);
        };

        addHandler(handler);

        action();
        await t.Task;

        removeHandler(handler);
    }

这使我&#34;无法将Lambda表达式转换为Type Delegate,因为它不是委托类型。&#34;在一开始。

1 个答案:

答案 0 :(得分:2)

试试这个作为你的定义。一定要爱仿制药!

public static async Task WaitUntilAsync<T>(this Action action, Action<T> addHandler, Action<T> removeHandler, Predicate<string> pred) where T : class

不幸的是,你不能使用委托作为通用约束,如下所示:

public static async Task WaitUntilAsync<T>(this Action action, Action<T> addHandler, Action<T> removeHandler, Predicate<string> pred) where T : EventHandler

...所以你必须使用反射确认你的类型,然后手动投射。

这是一个完整的例子:

  public static async Task WaitUntilAsync<TDelegate>(this Action action, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, Predicate<string> pred) where TDelegate : class
    {
        var delegateType = typeof(TDelegate);

        if (delegateType != typeof(EventHandler) && !delegateType.IsSubclassOf(typeof(EventHandler))) throw new Exception("TDelegate must be EventHandler or a subclass.");

        var t = new TaskCompletionSource<bool>();

        EventHandler realHandler = (sender, args) =>
        {
            //do real event work here
        };

        var handler = Delegate.CreateDelegate(delegateType, realHandler.Method) as TDelegate;

        addHandler(handler);

        action();
        await t.Task;

        removeHandler(handler);
    }