非委托类型的事件

我已经实现了一个看起来像这个接口的类:

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

此CustomEvent类的工作方式与MulticastDelegate非常相似。 它可以调用。 它可以与另一个CustomEvent结合使用。 并且可以从另一个CustomEvent中删除CustomEvent。

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

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

不幸的是,这段代码无法编译。 出现编译器错误CS0066:

‘EventProvider.MyEvent’:事件必须是委托类型

基本上,我需要的是一个添加删除访问器而不是getset的属性 。 我认为唯一的方法就是使用event关键字。 我知道一个明显的替代方案是声明两个可以添加和删除的方法,但我也想避免这种情况。

有谁知道这个问题是否有一个很好的解决方案? 我想知道是否有任何方法可以欺骗编译器接受非委托类型作为事件。 也许是自定义属性。

顺便说一下,有人在expert-exchange.com上提出了类似的问题。 由于该网站不是免费的,我看不到回复。 以下是主题: http : //www.experts-exchange.com/Programming/Languages/C_Sharp/Q_21697455.html

如果您希望能够从事件中添加和删除CustomEvent对象(而不是常规委托),则有两个选项:

从ICustomEvent到EventHandler(或其他一些委托)进行隐式转换,返回ICustomEvent的实例方法(可能是Invoke),然后使用委托的Target属性在addremove访问器中获取原始ICustomEvent。

编辑 :像这样:

 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 ),您仍然需要弄清楚如何添加第一个处理程序


创建一个CustomEvent类型的可写属性,然后重载+-运算符以允许属性上的+=-=

编辑 :为了防止你的调用者覆盖事件,你可以在CustomEvent中公开前一个值(我假设它的工作方式类似于一个不可变的堆栈 ),并在setter中添加

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

请注意,删除最后一个处理程序时, valuemyEvent.Previous都将为null

试试这个:

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

您可以向其添加和删除正常的EventHandler委托,它将执行addremove访问器。


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

你想要完成什么,你不能使用代表/事件?

这种尖叫重塑方形轮(页面底部) ,但这也可能是我不理解问题。

为什么不尝试在CustomEvent类上使用“+ =”和“ – =”运算符? 您不能直接覆盖“+ =”和“ – =”运算符,但它们由“+”和“ – ”运算符计算。

赋值运算符不能重载,但是+ =,例如,使用+来计算,可以重载。

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

因此,您可以使用可由+ =和 – =运算符组合的字段或属性,而不是使用类似事件的添加和删除方法。 此外,它将组合逻辑封装在您自己的CustomEvent类中。

卡洛斯洛斯。