C# - Why is there an error using EventHandler<T>?

Viewed 231

Doing a Pluralsight video and can't find out why it's wrong.

Error Message on this point:

worker.WorkPerformed += new EventHandler<WorkPerformedEventArgs>(worker_WorkPerformed);

Error Message:

Cannot implicity convert to type 'System.EventHandler<AB_Events.WorkPerformedEventArgs>' to 'AB_Events.WorkPerformedHandler'

Snippets

public delegate int WorkPerformedHandler(object sender,WorkPerformedEventArgs e);
public class Worker
{
    public event WorkPerformedHandler WorkPerformed;
    protected virtual void OnWorkPerformed(int hours, WorkType workType)
    {  
        var del = WorkPerformed as WorkPerformedHandler;
        if (del != null)
        {
            del(this, new WorkPerformedEventArgs(hours, workType));
        }
    }
}

And

class Program
{
    static void Main(string[] args)
    {
        var worker = new Worker();

        worker.WorkPerformed += new EventHandler<WorkPerformedEventArgs>(worker_WorkPerformed);

        Console.ReadKey();
    }

    public static void worker_WorkPerformed(object sender, WorkPerformedEventArgs e)
    {
        throw new NotImplementedException();
    }
}
2 Answers

Although methods and anonymous functions are implicitly convertible to a delegate type that matches their signature, a delegate instance is not implicitly convertible to another delegate type.

You need to use either EventHandler<TEventArgs> or your WorkPerformedHandler, but not both:

public class Worker
{
    public event WorkPerformedHandler WorkPerformed;
    
    //...
}

Or:

public class Worker
{
    public event EventHandler<WorkPerformedEventArgs> WorkPerformed;
    
    //...
}

Also, because worker_WorkPerformed can be implicitly converted to either type, the most concise syntax would be this:

worker.WorkPerformed += worker_WorkPerformed; // Implicit conversion

If you do go with your WorkPerformedHandler delegate, make sure you change the return type to void as per the signature of worker_WorkPerformed:

public delegate void WorkPerformedHandler(object sender, WorkPerformedEventArgs e);

It is generally not advisable to return from an event handler anyway, as there can be multiple subscribers.

what i have done is to replace WorkPerformedHandler by EventHandler<WorkPerformedEventArgs>

public delegate int WorkPerformedHandler(object sender, WorkPerformedEventArgs e);
public class Worker
{
    public event EventHandler<WorkPerformedEventArgs> WorkPerformed;
    protected virtual void OnWorkPerformed(WorkPerformedEventArgs e)
    {
        WorkPerformed?.Invoke(this, e);
    }
}

event subscription :

var worker = new Worker();
worker.WorkPerformed += new EventHandler<WorkPerformedEventArgs>(worker_WorkPerformed);
Related