"Michael Kennedy [UB]" <mk******@REMOV ETHIS.unitedbin ary.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.EventHan dler DoneIt;
"event" protects it from that sort of "abuse". If you change it to
public System.EventHan dler 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();
DoneItSubscribe r s1 = new DoneItSubscribe r( "First", b );
DoneItSubscribe r s2 = new DoneItSubscribe r( "Second", b );
Console.WriteLi ne( "Raising DoneIt Event." );
b.RaiseDoneIt() ;
Console.WriteLi ne( "Clearing DoneIt Event sinks." );
#if ClearEvent
b.ClearDoneIt() ;
#else
b.DoneIt = null;
#endif
Console.WriteLi ne( "Raising DoneIt Event again." );
b.RaiseDoneIt() ;
}
}
public class B {
#if ClearEvent
public event System.EventHan dler DoneIt;
#else
public System.EventHan dler 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
// "Programmin g .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.GetInvoc ationList();
foreach( Delegate del in delegates ){
EventHandler sink = (EventHandler)d el;
try {
sink( this, e );
} catch {
Console.WriteLi ne( "OnDoneIt: Eventhandler raised exception." );
}
}
} // End method B.OnDoneIt
} // end class B
public class DoneItSubscribe r {
private string name_;
public DoneItSubscribe r( string name, B eventSource ) {
name_ = name;
eventSource.Don eIt += new EventHandler( HandleDoneIt );
}
public void HandleDoneIt( object sender, EventArgs e ){
Console.WriteLi ne(
name_ + ": handled DoneIt."
);
}
} // end class DoneItSubscribe r
}