3

我无法编译以下代码。

编译错误 CS0079:事件“CustomEvent”只能出现在 += 或 -= 的左侧

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

我怎样才能使这项工作?

我的实现是这样的:

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
}
4

2 回答 2

6

您的编辑显示了一个递归调用:您正在声明一个自定义事件,这意味着要提供一个支持字段;例如:

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

请注意,Func我指的是字段( customEvent),而不是事件( CustomEvent)。

但是,这更简单更好(线程安全)作为类似字段的事件:

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

类似字段的事件使用event关键字,但省略了访问器:编译器为您添加了许多样板文件(支持字段和线程安全的添加/删除实现)。此外,它允许通过事件名称(来自声明类型)访问支持文件,因此该行是如何var tmp = CustomEvent;工作的。

另外:对静态事件要非常小心;它们是意外保持大量对象存活的好方法。

于 2012-12-22T07:59:45.390 回答
3

如果它是在当前类型中声明的类字段事件,则只能测试/调用事件。所以:有两种情况会导致这种情况:

  1. 它不是类似字段的事件,但具有自定义add/remove访问器:在这种情况下,只有您的自定义代码知道委托的存储方式

  2. 它没有在当前类型中声明,而是在基类型或一些不相关的对象中:在这种情况下,您需要获取声明类型来调用事件,通常通过OnCustomEvent方法。在基类型的情况下,约定是创建这个方法protected virtual,它允许子类调用事件通过override


(评论)

它看起来像案例1。但是,我不明白如何解决这个问题。

如果您有自定义add/ remove,那么如何调用它是特定于实现的(如果我能看到add/ ,我可以告诉您更多信息remove),但让我们看一下两个常见的实现:

1a:支持代表:

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

在这种情况下,“调用”实现将很简单:

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

或者如果您感到格外小心:

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

1b:an EventHandlerList(用于稀疏事件):

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

在这种情况下,调用实现将是:

var handler = (EventHandler)Events[SomeEventKey];
if(handler != null) handler(this, EventArgs.Empty);
于 2012-12-21T07:36:19.270 回答