非委托式的事件(Events of a non-delegate type)

2019-06-26 01:20发布

我已经实现了一个类,看起来像这样的界面:

[ImmutableObject(true)]
public interface ICustomEvent
{
    void Invoke(object sender, EventArgs e);

    ICustomEvent Combine(EventHandler handler);
    ICustomEvent Remove(EventHandler handler);

    ICustomEvent Combine(ICustomEvent other);
    ICustomEvent Remove(ICustomEvent other);
}

这个自定义事件类的工作就像一个MulticastDelegate。 它可以调用。 它可以与其它自定义事件相结合。 和自定义事件可以从另一个自定义事件被删除。

现在,我要声明一个类是这样的:

class EventProvider
{
    public event CustomEvent MyEvent;

    private void OnMyEvent()
    {
        var myEvent = this.MyEvent;
        if (myEvent != null) myEvent.Invoke(this, EventArgs.Empty);
    }
}

不幸的是,这段代码不能编译。 出现一个编译器错误CS0066:

“EventProvider.MyEvent”:事件必须是委托类型

基本上,我需要的是已经添加删除访问者,而不是获取设置属性。 我认为有,唯一的方法是使用event关键字。 我知道,一个显而易见的选择是声明了两个方法,会做的添加和删除,但我想避免这一点。

有谁知道,如果有一个很好的解决这个问题呢? 我不知道是否有任何方式骗取编译器接受非授权类型的事件。 自定义属性,也许。

顺便说一句,有人问在experts-exchange.com过类似的问题。 由于该网站是不是免费的,我看不到的响应。 这里是话题: http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_21697455.html

Answer 1:

如果您希望能够添加和删除CustomEvent从事件的对象(而不是常规的代表),有两种选择:

请从ICustomEvent到事件处理程序(或其他一些代表)隐式转换返回ICustomEvent的一个实例方法(可能调用),然后使用委托的目标属性来获取在原ICustomEvent addremove访问者。

编辑 :就像这样:

CustomEvent myEvent;
public event EventHandler MyEvent {
    add {
        if (value == null) throw new ArgumentNullException("value");
        var customHandler = value.Target as ICustomEvent;

        if (customHandler != null)
            myEvent = myEvent.Combine(customHandler);
        else
            myEvent = myEvent.Combine(value);   //An ordinary delegate
    }
    remove {
        //Similar code
    }
}

请注意,您仍然需要弄清楚如何添加第一个处理程序,如果它是一个委托(如果myEvent字段null


使型自定义事件的可写属性,那么重载+-运营商允许+=-=在属性。

编辑 :为了防止来电者被覆盖的情况下,你可能会暴露出自定义事件之前的值(我假设它就像一个不可改变的堆栈 ),并且在二传手,加

if (myEvent.Previous != value && value.Previous != myEvent)
    throw new ArgumentException("You cannot reset a CustomEvent", "value");

需要注意的是,当最后一个处理程序被删除,无论是valuemyEvent.Previous将是null



Answer 2:

试试这个:

CustomEvent myEvent

public event EventHandler MyEvent {
    add { myEvent = myEvent.Combine(value); }
    remove {myEvent = myEvent.Remove(value); }
}

您可以添加和删除正常的事件处理程序委托给它,它会执行addremove访问者。


编辑 :你可以找到一个弱事件实现这里 。
第二编辑 :还是在这里 。



Answer 3:

什么是你要完成的,你不能使用委托/事件?

这惨叫重塑方轮(在页面底部) ,但也可以同样是我不理解的问题。



Answer 4:

你为什么不尝试使用“+ =”和“ - =”运营商对您的自定义事件类? 你不能覆盖的“+ =”和“ - =”运营商直接,但它们是由“+”和评估“ - ”操作符。

赋值运算符不能被重载,但+ =,例如,使用+,它可以被重载评价。

http://msdn.microsoft.com/en-us/library/8edha89s(VS.90).aspx

因此,而不是具有事件性的添加和删除方法,你可以有一个字段或可以通过+ =和组合属性 - =运营商。 除了它封装了自己的自定义事件类中的组合逻辑。

卡洛斯·洛思。



文章来源: Events of a non-delegate type