我已经实现了一个类,看起来像这样的界面:
[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
如果您希望能够添加和删除CustomEvent
从事件的对象(而不是常规的代表),有两种选择:
请从ICustomEvent到事件处理程序(或其他一些代表)隐式转换返回ICustomEvent的一个实例方法(可能调用),然后使用委托的目标属性来获取在原ICustomEvent add
和remove
访问者。
编辑 :就像这样:
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");
需要注意的是,当最后一个处理程序被删除,无论是value
和myEvent.Previous
将是null
。
试试这个:
CustomEvent myEvent
public event EventHandler MyEvent {
add { myEvent = myEvent.Combine(value); }
remove {myEvent = myEvent.Remove(value); }
}
您可以添加和删除正常的事件处理程序委托给它,它会执行add
和remove
访问者。
编辑 :你可以找到一个弱事件实现这里 。
第二编辑 :还是在这里 。
什么是你要完成的,你不能使用委托/事件?
这惨叫重塑方轮(在页面底部) ,但也可以同样是我不理解的问题。
你为什么不尝试使用“+ =”和“ - =”运营商对您的自定义事件类? 你不能覆盖的“+ =”和“ - =”运营商直接,但它们是由“+”和评估“ - ”操作符。
赋值运算符不能被重载,但+ =,例如,使用+,它可以被重载评价。
http://msdn.microsoft.com/en-us/library/8edha89s(VS.90).aspx
因此,而不是具有事件性的添加和删除方法,你可以有一个字段或可以通过+ =和组合属性 - =运营商。 除了它封装了自己的自定义事件类中的组合逻辑。
卡洛斯·洛思。