G
Guest
First... let's deal with Delegates. Comments welcome.
1) Invoking a NULL delegate is annoying.
** (It should just do nothing rather than crash.)
2) It's too easy to accidently attach multiple redundant handlers onto
delegates.
3) A delegate might point to handlers on objects that are out of scope or
been disposed, causing those objects to crash.
** (Handlers should be removed automatically when the object that defines
them leaves scope).
4) ?
5) ?
There is sort of a potential for "delegate leak" where objects attach
handlers indefinitely while the handler functions get called an increasing
number of times per event...
Unfortunately, the way to prevent the aforementioned problems is not
convenient...
So, for protective coding... must we truly declare the laws of proper
delegate usage as follows? (I hope we can resolve a more convenient way).
////////////////////////////////////////////////////////
///// ALL CLASSES THAT ATTACH TO THE EVENT CHAIN MUST...
// declare member variable of this
System.EventHandler _hEventHandler;
// during construction of this:
_hEventHandler = new System.EventHandler(whatever);
// during initialization of this:
_obj._SomeEvent += _hEventHandler;
// during disposal of this: (all users must call Dispose)
_obj._SomeEvent -= _hEventHandler;
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
///// ALL CLASSES SERVING AN EVENT MUST...
////////////////////////////////////////////////////////
public event System.EventHandler _SomeEvent
{
add
{
// PREVENTS THE SAME HANDLER FROM BEING ATTACHED MORE THAN ONCE
Attach(ref _eSomeEvent, value);
}
remove
{
_eSomeEvent -= value;
}
}
private event System.EventHandler _eSomeEvent;
private void _FireSomeEvent()
{
Fire(_eSomeEvent, this, whatever);
}
public static void Fire(System.EventHandler h, object sender,
System.EventArgs args)
{
// PROTECTS FROM EVENT INVOKED WHEN NULL
if(h!=null) h(sender, args);
}
public static void Attach(ref System.EventHandler h1, System.EventHandler h2)
{
// PROTECTS FROM SAME HANDLER BEING ADDED MULTIPLE TIMES
if(h2==null) return;
if(h1!=null)
{
System.Delegate[] ar = h1.GetInvocationList();
foreach(System.Delegate dg in ar) if(dg == h2) return;
}
// (this is okay when h1 is null)
h1 += h2;
}
1) Invoking a NULL delegate is annoying.
** (It should just do nothing rather than crash.)
2) It's too easy to accidently attach multiple redundant handlers onto
delegates.
3) A delegate might point to handlers on objects that are out of scope or
been disposed, causing those objects to crash.
** (Handlers should be removed automatically when the object that defines
them leaves scope).
4) ?
5) ?
There is sort of a potential for "delegate leak" where objects attach
handlers indefinitely while the handler functions get called an increasing
number of times per event...
Unfortunately, the way to prevent the aforementioned problems is not
convenient...
So, for protective coding... must we truly declare the laws of proper
delegate usage as follows? (I hope we can resolve a more convenient way).
////////////////////////////////////////////////////////
///// ALL CLASSES THAT ATTACH TO THE EVENT CHAIN MUST...
// declare member variable of this
System.EventHandler _hEventHandler;
// during construction of this:
_hEventHandler = new System.EventHandler(whatever);
// during initialization of this:
_obj._SomeEvent += _hEventHandler;
// during disposal of this: (all users must call Dispose)
_obj._SomeEvent -= _hEventHandler;
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
///// ALL CLASSES SERVING AN EVENT MUST...
////////////////////////////////////////////////////////
public event System.EventHandler _SomeEvent
{
add
{
// PREVENTS THE SAME HANDLER FROM BEING ATTACHED MORE THAN ONCE
Attach(ref _eSomeEvent, value);
}
remove
{
_eSomeEvent -= value;
}
}
private event System.EventHandler _eSomeEvent;
private void _FireSomeEvent()
{
Fire(_eSomeEvent, this, whatever);
}
public static void Fire(System.EventHandler h, object sender,
System.EventArgs args)
{
// PROTECTS FROM EVENT INVOKED WHEN NULL
if(h!=null) h(sender, args);
}
public static void Attach(ref System.EventHandler h1, System.EventHandler h2)
{
// PROTECTS FROM SAME HANDLER BEING ADDED MULTIPLE TIMES
if(h2==null) return;
if(h1!=null)
{
System.Delegate[] ar = h1.GetInvocationList();
foreach(System.Delegate dg in ar) if(dg == h2) return;
}
// (this is okay when h1 is null)
h1 += h2;
}