0

我在 C# 中有这样一个类和委托:

public delegate void Super();
public class Event
{
    public event Super activate ;
    public void act()
    {
       if (activate != null) 
           activate();
    }
}

我需要用 C++/CLI 重写它。但我有一个错误 -usage requires Event::activate to be data member

public delegate void Super();
public ref class Event
{
    public:
        event Super ^activate;
        void act()
        {
            if (activate!=nullptr) 
                activate();
        }
};

是不是activate()通话有问题?

4

1 回答 1

3

IIRC,在 C++/CLI 中你不需要空测试,编译器会为你插入它。打电话

activate();

MSDN证实了这一点:

下面的代码示例演示了用于生成琐碎事件的 raise 方法的逻辑:如果事件有一个或多个订阅者,则raise隐式调用该方法或显式调用委托。如果委托的返回类型不是void并且事件订阅者为零,则该raise方法返回委托类型的默认值。如果没有事件订阅者,则调用该raise方法只会返回并且不会引发异常。如果委托返回类型不是void,则返回委托类型。

这是一件非常好的事情,因为 C# 鼓励竞争条件(您发布的代码有一个)。C++/CLI 编译器不会在 null 检查和调用之间重新读取支持字段,因此它是线程安全的,无需额外工作。与 C++/CLI 编译器生成的内容等效的正确 C# 版本是:

var activate_copy = activate;
if (activate_copy != null) 
    activate_copy();
于 2012-05-05T23:17:18.397 回答