问题
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:
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 storedit 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 methodprotected virtual
, which allows sub-classes to invoke the event and hook into the event viaoverride
(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