简体   繁体   中英

C# CS0079 Event Handling Compile Errors

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
}

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.

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM