C# CS0079 Event Handling Compile Errors

随声附和 提交于 2021-01-27 15:45:54

问题


I can't compile the following code.

Compile error CS0079 : The event 'CustomEvent' can only appear on the left hand side of += or -=

if (CustomEvent != null)   //CS0079
    CustomEvent(null, null);  //CS0079

How can I make this work?

My implementation is like this:

public delegate void EventHandler(object sender, EventArgs e);  
public static event EventHandler CustomEvent
{
    add    { CustomEvent += value; }
    remove { CustomEvent -= value; }
 }
private static void Func()
{
    if (CustomEvent != null)      //CS0079
        CustomEvent(null, null);  //CS0079
}

回答1:


Your edit shows a recursive call: you are declaring a custom event, which means you are meant to provide a backing field; for example:

private static EventHandler customEvent;
public static event EventHandler CustomEvent
{
    add    { customEvent += value; }
    remove { customEvent -= value; }
 }
private static void Func()
{
    var tmp = customEvent;
    if (tmp != null) tmp(null, null);
}

Note that in Func I am referring to the field (customEvent), not the event (CustomEvent).

However, this is simpler are better (thread-safe) as a field-like event:

public static event EventHandler CustomEvent;
private static void Func()
{
    var tmp = CustomEvent;
    if (tmp != null) tmp(null, null);
}

A field-like event uses the event keyword, but omits the accessors: the compiler adds a lot of boilerplate for you (a backing field, and thread-safe add/remove implementations). Further, it allows access to the backing filed via the event name (from the declaring type), hence how the line var tmp = CustomEvent; works.

Also: be very careful with static events; they are a great way to accidentally keep lots of objects alive.




回答2:


You can only test/invoke an event if it is a field-like event declared in the current type. So: there are two scenarios that would cause this:

  1. it isn't a field-like event, but has custom add/remove accessors: in which case, only your custom code knows how the delegate is stored

  2. it isn't declared in the current type, but is in a base-type or some unrelated object: in which case, you'll need to get the declaring type to invoke the event, usually via an OnCustomEvent method. In the case of a base-type, the convention would be to make this method protected virtual, which allows sub-classes to invoke the event and hook into the event via override


(comments)

It looks like the case1. however, I don't understand what to do to resolve this issue.

If you have custom add/remove, then how to invoke it is implementation-specific (I could tell you more if I could see the add/remove), but let's look at two common implementations:

1a: a backing delegate:

private EventHandler someEvent;
public event EventHandler SomeEvent
{
    add { someEvent += value; }
    remove { someEvent -= value; }
}

in this case, the "invoke" implementation would be simply:

if(someEvent != null) someEvent(this, EventArgs.Empty);

or if you are feeling extra-cautious:

var handler = someEvent;
if(handler != null) handler(this, EventArgs.Empty);

1b: an EventHandlerList (used for sparse events):

private static readonly object SomeEventKey = new object();
public event EventHandler SomeEvent
{
    add { Events.AddHandler(SomeEventKey, value); }
    remove { Events.RemoveHandler(SomeEventKey, value); }
}

in which case the invoke implementation would be:

var handler = (EventHandler)Events[SomeEventKey];
if(handler != null) handler(this, EventArgs.Empty);


来源:https://stackoverflow.com/questions/13985889/c-sharp-cs0079-event-handling-compile-errors

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!