B
Bill Woodruff
WinForms app, C#, .Net 2.0, Visual Studio 2005, all the flavors of the
FrameWork (and service packs) installed up to 3.5
Hi,
I assume you're all familiar with the typical way you define an Event using
a Delegate EventHandler, perhaps creating a CustomEventArgs that convey
additional parameters to other Windows Event Handlers or units of code that
register to "receive" the event. Something like "Exhibit A" at the end of
this message. We are all familiar, I think it's fair to say, with the :
object Sender, EventArgsofSomeType e
Parameter requirements. And I would guess we have experience with the often
required casting involved to turn Sender into some type we need to deal
with, or using modified EventArgs to pass instances of whatever types.
As an experiment I have modified the whole nature of an EventHandler, done
away with "object sender" and "EventArgsofSomeTyp e," and in essence
"tightly bound " the code to existing objects I know are persistent in my
application. See Exhibit B attached below.
Using the techniques shown in "Exhibit B" I eliminate any need for casting
by the subscribers to the event (as long as they have the reference to the
type of the passed object). I still get the += facility "kicking in" in the
IDE with auto-complete for this modded Event code.
And comparing one instance implemented with techniques in Ex. A with another
instance implemented with techniques in Ex. B : seem to get the same
run-time functionality.
Each of the "exhibits" is in the context of a run-time created Form which
does not have its parent property set to the MainAppForm. Each run-time
created Form is instanced from a configured Form Template which contains a
single button. When that button is clicked the Click Event Handler calls
OnIndependentMessage1 : in exhibit A as you can see passing an object and a
custom EventArgs; in exhibit B passing only the pointer to the current
executing run-time form on which the button click has occurred.
My questions :
1. is what I am doing flat-out wrong/bad/blasphemy/poor coding in your
opinion ?
2. what issues could arise from not following the standard .NET event
Sender, EventArgs parameter order structure. I'm assuming there are issues
other than the developer has to carry a slightly more "heavy" weight mental
model.
3. if you would use a technique like this, in what scenarios would you use
it and why.
4. could this technique, by eliminating casts and lookups contribute any
real increase in speed or whatever in apps ? In other words, given you Can
use it, is it worth using ?
many thanks for your examining and commenting on this. the code has
unusually long verbose variable names because I am writing it as an
educational tool to demonstrate an alternate way to Raise Events ... even if
using the technique is not a "good thing" I think it will have educational
value as a way to focus in on exactly how the Event raising is done now by
contrasting its dynamic behavior and structure with the existing model.
"Escapee from the Island of Dr. Moreau" ?, hack ?, possibly useful ? You are
the judge.
best, Bill Woodruff
dotScience
Chiang Mai, Thailand
// Exhibit A ... from working code ...
#region 'IndependentWindowMessage1' event definition code
// Delegate method prototype that event receivers must implement
public delegate void
IndependentWindowMessage1EventHandler(SecondaryIndependentWindow
theIWindow);
// Private delegate linked list (explicitly defined)
private IndependentWindowMessage1EventHandler
IndependentWindowMessage1EventHandlerDelegate;
// Main event definition
public event IndependentWindowMessage1EventHandler IndependentEvent1
{
// Explicit event definition with accessor methods
add
{
IndependentWindowMessage1EventHandlerDelegate =
(IndependentWindowMessage1EventHandler)Delegate.Combine(IndependentWindowMessage1EventHandlerDelegate,
value);
}
remove
{
IndependentWindowMessage1EventHandlerDelegate =
(IndependentWindowMessage1EventHandler)Delegate.Remove(IndependentWindowMessage1EventHandlerDelegate,
value);
}
}
// This is the method that is responsible for notifying
// receivers that the event occurred
protected virtual void OnIndependentMessage1(SecondaryIndependentWindow
theIWindow)
{
if (IndependentWindowMessage1EventHandlerDelegate != null)
{
IndependentWindowMessage1EventHandlerDelegate(theIWindow);
}
}
#endregion //('IndependentEvent1' event definition code)
private void btn_IndependentWindowSendMessage_Click(object sender,
EventArgs e)
{
OnIndependentMessage1(this);
}
Exhibit B ... from working code ... created by modifying Exhibit A code ...
#region 'IndependentWindowMessage1' event definition code
// Delegate method prototype that event receivers must implement
public delegate void
IndependentWindowMessage1EventHandler(SecondaryIndependentWindow
theIWindow);
// Private delegate linked list (explicitly defined)
private IndependentWindowMessage1EventHandler
IndependentWindowMessage1EventHandlerDelegate;
// Main event definition
public event IndependentWindowMessage1EventHandler IndependentEvent1
{
// Explicit event definition with accessor methods
add
{
IndependentWindowMessage1EventHandlerDelegate =
(IndependentWindowMessage1EventHandler)Delegate.Combine(IndependentWindowMessage1EventHandlerDelegate,
value);
}
remove
{
IndependentWindowMessage1EventHandlerDelegate =
(IndependentWindowMessage1EventHandler)Delegate.Remove(IndependentWindowMessage1EventHandlerDelegate,
value);
}
}
// This is the method that is responsible for notifying
// receivers that the event occurred
protected virtual void
OnIndependentMessage1(SecondaryIndependentWindow theIWindow)
{
if (IndependentWindowMessage1EventHandlerDelegate != null)
{
IndependentWindowMessage1EventHandlerDelegate(theIWindow);
}
}
#endregion //('IndependentEvent1' event definition code)
private void btn_IndependentWindowSendMessage_Click(object sender,
EventArgs e)
{
OnIndependentMessage1(this);
}
FrameWork (and service packs) installed up to 3.5
Hi,
I assume you're all familiar with the typical way you define an Event using
a Delegate EventHandler, perhaps creating a CustomEventArgs that convey
additional parameters to other Windows Event Handlers or units of code that
register to "receive" the event. Something like "Exhibit A" at the end of
this message. We are all familiar, I think it's fair to say, with the :
object Sender, EventArgsofSomeType e
Parameter requirements. And I would guess we have experience with the often
required casting involved to turn Sender into some type we need to deal
with, or using modified EventArgs to pass instances of whatever types.
As an experiment I have modified the whole nature of an EventHandler, done
away with "object sender" and "EventArgsofSomeTyp e," and in essence
"tightly bound " the code to existing objects I know are persistent in my
application. See Exhibit B attached below.
Using the techniques shown in "Exhibit B" I eliminate any need for casting
by the subscribers to the event (as long as they have the reference to the
type of the passed object). I still get the += facility "kicking in" in the
IDE with auto-complete for this modded Event code.
And comparing one instance implemented with techniques in Ex. A with another
instance implemented with techniques in Ex. B : seem to get the same
run-time functionality.
Each of the "exhibits" is in the context of a run-time created Form which
does not have its parent property set to the MainAppForm. Each run-time
created Form is instanced from a configured Form Template which contains a
single button. When that button is clicked the Click Event Handler calls
OnIndependentMessage1 : in exhibit A as you can see passing an object and a
custom EventArgs; in exhibit B passing only the pointer to the current
executing run-time form on which the button click has occurred.
My questions :
1. is what I am doing flat-out wrong/bad/blasphemy/poor coding in your
opinion ?
2. what issues could arise from not following the standard .NET event
Sender, EventArgs parameter order structure. I'm assuming there are issues
other than the developer has to carry a slightly more "heavy" weight mental
model.
3. if you would use a technique like this, in what scenarios would you use
it and why.
4. could this technique, by eliminating casts and lookups contribute any
real increase in speed or whatever in apps ? In other words, given you Can
use it, is it worth using ?
many thanks for your examining and commenting on this. the code has
unusually long verbose variable names because I am writing it as an
educational tool to demonstrate an alternate way to Raise Events ... even if
using the technique is not a "good thing" I think it will have educational
value as a way to focus in on exactly how the Event raising is done now by
contrasting its dynamic behavior and structure with the existing model.
"Escapee from the Island of Dr. Moreau" ?, hack ?, possibly useful ? You are
the judge.
best, Bill Woodruff
dotScience
Chiang Mai, Thailand
// Exhibit A ... from working code ...
#region 'IndependentWindowMessage1' event definition code
// Delegate method prototype that event receivers must implement
public delegate void
IndependentWindowMessage1EventHandler(SecondaryIndependentWindow
theIWindow);
// Private delegate linked list (explicitly defined)
private IndependentWindowMessage1EventHandler
IndependentWindowMessage1EventHandlerDelegate;
// Main event definition
public event IndependentWindowMessage1EventHandler IndependentEvent1
{
// Explicit event definition with accessor methods
add
{
IndependentWindowMessage1EventHandlerDelegate =
(IndependentWindowMessage1EventHandler)Delegate.Combine(IndependentWindowMessage1EventHandlerDelegate,
value);
}
remove
{
IndependentWindowMessage1EventHandlerDelegate =
(IndependentWindowMessage1EventHandler)Delegate.Remove(IndependentWindowMessage1EventHandlerDelegate,
value);
}
}
// This is the method that is responsible for notifying
// receivers that the event occurred
protected virtual void OnIndependentMessage1(SecondaryIndependentWindow
theIWindow)
{
if (IndependentWindowMessage1EventHandlerDelegate != null)
{
IndependentWindowMessage1EventHandlerDelegate(theIWindow);
}
}
#endregion //('IndependentEvent1' event definition code)
private void btn_IndependentWindowSendMessage_Click(object sender,
EventArgs e)
{
OnIndependentMessage1(this);
}
Exhibit B ... from working code ... created by modifying Exhibit A code ...
#region 'IndependentWindowMessage1' event definition code
// Delegate method prototype that event receivers must implement
public delegate void
IndependentWindowMessage1EventHandler(SecondaryIndependentWindow
theIWindow);
// Private delegate linked list (explicitly defined)
private IndependentWindowMessage1EventHandler
IndependentWindowMessage1EventHandlerDelegate;
// Main event definition
public event IndependentWindowMessage1EventHandler IndependentEvent1
{
// Explicit event definition with accessor methods
add
{
IndependentWindowMessage1EventHandlerDelegate =
(IndependentWindowMessage1EventHandler)Delegate.Combine(IndependentWindowMessage1EventHandlerDelegate,
value);
}
remove
{
IndependentWindowMessage1EventHandlerDelegate =
(IndependentWindowMessage1EventHandler)Delegate.Remove(IndependentWindowMessage1EventHandlerDelegate,
value);
}
}
// This is the method that is responsible for notifying
// receivers that the event occurred
protected virtual void
OnIndependentMessage1(SecondaryIndependentWindow theIWindow)
{
if (IndependentWindowMessage1EventHandlerDelegate != null)
{
IndependentWindowMessage1EventHandlerDelegate(theIWindow);
}
}
#endregion //('IndependentEvent1' event definition code)
private void btn_IndependentWindowSendMessage_Click(object sender,
EventArgs e)
{
OnIndependentMessage1(this);
}