没有 - =清除事件 [英] Clearing Events without -=

查看:59
本文介绍了没有 - =清除事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我有一种情况需要在自定义类中清除事件接收器

。但我不知道哪些方法报名参加了

活动。


请考虑以下示例:


公共班级B

{

公共活动System.EventHandler DoneIt;


// ....

}


B b =新B();

b.DoneIt + = X;


现在最终我想要重置 b这样DoneIt == null但是我不想完全生成一个新对象,只需要事件接收器。

通常这是使用


b.DoneIt - = X;


但在这种情况下,我们不知道X是什么。 B在班级图书馆,我们

无法控制或知道该班级的消费者可能做什么

与DoneIt。


我的问题是:有没有办法让b强制DoneIt为null而没有

明确地知道+ =的右边因为它发生在我们的外面

代码?


在此先感谢,

Michael


ps如果您之前没有尝试过这个:b.DoneIt = null;不编译。

解决方案

Michael Kennedy [UB]< mk ****** @ REMOVETHIS.unitedbinary.com>写道:

我有一种情况需要从自定义类中的事件中清除事件接收器。但是我不知道哪些方法报名参加了这个
活动。




如果你不是所有者。自定义类,你不能这样做。

在自定义类中你可以清除事件,但如果自定义

类没有做任何清除可用事件的方法,它可能不希望你能够这样做。


-

Jon Skeet - < sk *** @ pobox.com>
http://www.pobox.com/~skeet

如果回复小组,请不要给我发邮件


< blockquote>使用反射,你可以做b.GetType()。GetEvents()或

b.GetType()。GetEvent()找到感兴趣的特定事件并使用

EventInfo.RemoveEventHandler()删除它。


我没有这样做,但快速查看文档会让我开始

这里。


Pete


" Michael Kennedy [UB]" < MK ****** @ REMOVETHIS.unitedbinary.com>写在

消息新闻:uv ************** @ tk2msftngp13.phx.gbl ...


我有一种情况需要从自定义类中的事件中清除事件接收器。但是我不知道哪些方法报名参加了这个
活动。

考虑以下例子:

公共课B
{
// ....
}
B b = new B();
b。 DoneIt + = X;

现在最终我想要重置 b这样DoneIt == null但是我不想完全生成一个新对象,只是事件下沉。
通常这是使用

b.DoneIt完成的 - = X;

但在这种情况下,我们不知道X是什么。 B在班级图书馆,我们无法控制或知道该班级的消费者可以用DoneIt做什么。

我的问题是:有没有办法如果没有明确知道+ =的右侧,那么b强制DoneIt为null,因为它发生在我们的代码之外?

提前致谢,
迈克尔

ps如果您之前没有尝试过这种方法:b.DoneIt = null;没有
编译。



" Michael Kennedy [UB]" < MK ****** @ REMOVETHIS.unitedbinary.com>写道:


< snip>

ps如果你以前没有尝试过这个:b.DoneIt = null;没有编译。




多数民众赞成因为你使用了


公共事件System.EventHandler DoneIt;

" event"保护它免受那种滥用。如果你将它更改为


public System.EventHandler DoneIt;


编译错误将消失 - 但是现在你有一个公开的

可访问字段,对象的客户端可以在不知情的情况下滥用

对象 - 应该避免的情况。只需在B类中创建公共方法

即可清除事件接收列表,例如:


public void ClearDoneIt(){

//在此处放置任何支票以确定

//您要遵循建议

//清除DoneIt

DoneIt = null;

} //结束方法B.RaiseDoneIt


这样你就不必离开事件接收器列表了。< b / b
源代码如下:


#define ClearEvent

使用系统;


命名空间ClearEvent {


class TestDriver {

static void Main(string [] args){


B b = new B();

DoneItSubscriber s1 = new DoneItSubscriber(" First",b);

DoneItSubscriber s2 = new DoneItSubscriber(" Second", b);

Console.WriteLine(Raising DoneIt Event。);

b.RaiseDoneIt();

Console.WriteLine (&quo t;清除DoneIt事件汇。 );

#if ClearEvent

b.ClearDoneIt();

#else

b.DoneIt = null ;

#endif

Console.WriteLine(再次提升DoneIt事件。;

b.RaiseDoneIt();

}

}


公共等级B {


#if ClearEvent
公共事件System.EventHandler DoneIt;

#else

public System.EventHandler DoneIt;

#endif


public void RaiseDoneIt(){

OnDoneIt(EventArgs.Empty);

} //结束方法B.RaiseDoneIt


public void ClearDoneIt(){

//在此处放置任何支票以确定

//您要遵循建议

//清除DoneIt

DoneIt = null;

} //结束方法B.RaiseDoneIt


//防御性地发布事件 p.108

//编程.NET组件作者:Juval L?wry,2003年4月O''Reilly& Associates Inc

// ISBN 0596003471

protected void OnDoneIt(EventArgs e){

if(null == DoneIt)return;


委托[]委托= DoneIt.GetInvocationList();

foreach(代表委托代表){

EventHandler sink =(EventHandler) del;

尝试{

sink(this,e);


} catch {

Console.WriteLine(" OnDoneIt:Eventhandler引发异常。);

}

}

} //结束方法B.OnDoneIt


} //结束班级B


公共类DoneItSubscriber {

私人字符串名称_;


public DoneItSubscriber(字符串名称,B eventSource){

name_ = name;

eventSource.DoneIt + = new EventHandler(HandleDoneIt); < br $>
}


public void HandleDoneIt(对象发送者,EventArgs e){

Console.WriteLine(

name_ +" ;:处理DoneIt。"

);

}

} //结束课DoneItSubscriber


}


Hi,

I have a situation where I need to clear the event sinks from an event
inside a custom class. But I don''t know which methods signed up for that
event.

Consider the following example:

public class B
{
public event System.EventHandler DoneIt;

// ....
}

B b = new B();
b.DoneIt += X;

Now eventually suppose I want to "reset" b so that DoneIt == null but I
don''t want to completely generate a new object, just the event sinks.
Typically this is done using

b.DoneIt -= X;

But in this case we don''t know what X is. B is in a class library and we
have no control or knowedge of what the consumers of that class might do
with DoneIt.

My question is: Is there a way to have b force DoneIt to be null without
explicitly knowing the right hand side of += since it happened outside our
code?

Thanks in advance,
Michael

ps In case you haven''t tried this before: b.DoneIt = null; does not compile.

解决方案

Michael Kennedy [UB] <mk******@REMOVETHIS.unitedbinary.com> wrote:

I have a situation where I need to clear the event sinks from an event
inside a custom class. But I don''t know which methods signed up for that
event.



If you are not the "owner" of the custom class, you can''t do this.
Within the custom class you can clear the event, but if the custom
class doesn''t make any means of clearing the event available to you, it
presumably doesn''t want you to be able to do so.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too


Using reflection, you can do b.GetType().GetEvents() or
b.GetType().GetEvent() to find the particular event of interest and use the
EventInfo.RemoveEventHandler() to remove it.

I haven''t done this, but a quick look at the docs would lead me to start
here.

Pete

"Michael Kennedy [UB]" <mk******@REMOVETHIS.unitedbinary.com> wrote in
message news:uv**************@tk2msftngp13.phx.gbl...

Hi,

I have a situation where I need to clear the event sinks from an event
inside a custom class. But I don''t know which methods signed up for that
event.

Consider the following example:

public class B
{
public event System.EventHandler DoneIt;

// ....
}

B b = new B();
b.DoneIt += X;

Now eventually suppose I want to "reset" b so that DoneIt == null but I
don''t want to completely generate a new object, just the event sinks.
Typically this is done using

b.DoneIt -= X;

But in this case we don''t know what X is. B is in a class library and we
have no control or knowedge of what the consumers of that class might do
with DoneIt.

My question is: Is there a way to have b force DoneIt to be null without
explicitly knowing the right hand side of += since it happened outside our
code?

Thanks in advance,
Michael

ps In case you haven''t tried this before: b.DoneIt = null; does not compile.



"Michael Kennedy [UB]" <mk******@REMOVETHIS.unitedbinary.com> wrote:

<snip>

ps In case you haven''t tried this before: b.DoneIt = null; does not compile.



Thats because you used

public event System.EventHandler DoneIt;

"event" protects it from that sort of "abuse". If you change it to

public System.EventHandler DoneIt;

the compilation error will go away - however now you have a publically
accessible field that clients of the object can abuse without the knowledge
of the object - a situation that should be avoided. Simply create a public method
in class B to clear the event sink list, e.g.:

public void ClearDoneIt(){
// Place any Checks here to determine
// it you want to follow the "suggestion"
// to clear DoneIt
DoneIt = null;
} // End method B.RaiseDoneIt

that way you won''t have to leave the event sink list so exposed.

Source Code follows:

#define ClearEvent
using System;

namespace ClearEvent {

class TestDriver {
static void Main(string[] args) {

B b = new B();
DoneItSubscriber s1 = new DoneItSubscriber( "First", b );
DoneItSubscriber s2 = new DoneItSubscriber( "Second", b );
Console.WriteLine( "Raising DoneIt Event." );
b.RaiseDoneIt();
Console.WriteLine( "Clearing DoneIt Event sinks." );
#if ClearEvent
b.ClearDoneIt();
#else
b.DoneIt = null;
#endif
Console.WriteLine( "Raising DoneIt Event again." );
b.RaiseDoneIt();
}
}

public class B {

#if ClearEvent
public event System.EventHandler DoneIt;
#else
public System.EventHandler DoneIt;
#endif

public void RaiseDoneIt(){
OnDoneIt( EventArgs.Empty );
} // End method B.RaiseDoneIt

public void ClearDoneIt(){
// Place any Checks here to determine
// it you want to follow the "suggestion"
// to clear DoneIt
DoneIt = null;
} // End method B.RaiseDoneIt

// "Publishing Events Defensively" p.108
// "Programming .NET Components" by Juval L?wry, April 2003 O''Reilly & Associates Inc
// ISBN 0596003471
protected void OnDoneIt( EventArgs e ){
if (null == DoneIt ) return;

Delegate[] delegates = DoneIt.GetInvocationList();
foreach( Delegate del in delegates ){
EventHandler sink = (EventHandler)del;
try {
sink( this, e );

} catch {
Console.WriteLine( "OnDoneIt: Eventhandler raised exception." );
}
}
} // End method B.OnDoneIt

} // end class B

public class DoneItSubscriber {
private string name_;

public DoneItSubscriber( string name, B eventSource ) {
name_ = name;
eventSource.DoneIt += new EventHandler( HandleDoneIt );
}

public void HandleDoneIt( object sender, EventArgs e ){
Console.WriteLine(
name_ + ": handled DoneIt."
);
}
} // end class DoneItSubscriber

}


这篇关于没有 - =清除事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆