<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Intercepting Add and Remove of C# Event Delegates</title>
	<atom:link href="http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/</link>
	<description>Mike Gavaghan blogs on Java, C#, .Net, and the software industry</description>
	<lastBuildDate>Sat, 26 Nov 2011 17:37:47 -0700</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Brij Sharma</title>
		<link>http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/comment-page-1/#comment-878</link>
		<dc:creator>Brij Sharma</dc:creator>
		<pubDate>Sat, 26 Nov 2011 17:37:47 +0000</pubDate>
		<guid isPermaLink="false">http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/#comment-878</guid>
		<description>I always use += and -= to manage adding and removing event handlers.
To explicitly do it in your code is something which I don&#039;t think is required but like in the topic above is good to show off.</description>
		<content:encoded><![CDATA[<p>I always use += and -= to manage adding and removing event handlers.<br />
To explicitly do it in your code is something which I don&#8217;t think is required but like in the topic above is good to show off.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Hi Vis Jacket</title>
		<link>http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/comment-page-1/#comment-840</link>
		<dc:creator>Hi Vis Jacket</dc:creator>
		<pubDate>Tue, 11 Jan 2011 14:05:50 +0000</pubDate>
		<guid isPermaLink="false">http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/#comment-840</guid>
		<description>A lot of good feedback on this article, thanks to everyone for sharing.  Just like most things with Windows, there is more than 1 way to do things.  More than 1 way to skin a cat, I suppose. ;D

I don&#039;t have the need to dig further under the hood, so the += and -= operators work just fine for our every day applications, but it&#039;s nice to know we can expand on that if needed.</description>
		<content:encoded><![CDATA[<p>A lot of good feedback on this article, thanks to everyone for sharing.  Just like most things with Windows, there is more than 1 way to do things.  More than 1 way to skin a cat, I suppose. ;D</p>
<p>I don&#8217;t have the need to dig further under the hood, so the += and -= operators work just fine for our every day applications, but it&#8217;s nice to know we can expand on that if needed.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Zachary</title>
		<link>http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/comment-page-1/#comment-834</link>
		<dc:creator>Zachary</dc:creator>
		<pubDate>Fri, 03 Sep 2010 16:52:29 +0000</pubDate>
		<guid isPermaLink="false">http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/#comment-834</guid>
		<description>Echoing what Hank Hatch says below, using this direct wrap function enables you to wrap built in .NET classes like BackgroundWorker and abstract an Interface for testing purposes (ie generating mocks etc) and using the Decorator Pattern (ref Head First Design Patterns).

Hank Hatch Says: 

November 3rd, 2008 at 11:46 am 
Also it is more of a direct wrap to do it like this -&gt;

private StateMachineEventHandler canTransition;
public event StateMachineEventHandler CanTranistion
{
add { this.canTransition += value; }
remove { this.canTransition -= value; }
}

which is pretty darn simple considering the power it can give you.</description>
		<content:encoded><![CDATA[<p>Echoing what Hank Hatch says below, using this direct wrap function enables you to wrap built in .NET classes like BackgroundWorker and abstract an Interface for testing purposes (ie generating mocks etc) and using the Decorator Pattern (ref Head First Design Patterns).</p>
<p>Hank Hatch Says: </p>
<p>November 3rd, 2008 at 11:46 am<br />
Also it is more of a direct wrap to do it like this -&gt;</p>
<p>private StateMachineEventHandler canTransition;<br />
public event StateMachineEventHandler CanTranistion<br />
{<br />
add { this.canTransition += value; }<br />
remove { this.canTransition -= value; }<br />
}</p>
<p>which is pretty darn simple considering the power it can give you.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Levi</title>
		<link>http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/comment-page-1/#comment-218</link>
		<dc:creator>Levi</dc:creator>
		<pubDate>Thu, 26 Feb 2009 06:08:30 +0000</pubDate>
		<guid isPermaLink="false">http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/#comment-218</guid>
		<description>Actually, the most common reason to implement an add &amp; remove on an event is for memory consumption.  For instance, let&#039;s say you have a type which has a large number of events.  If those events are defined with just a public event field, then the type has to allocate store for each delegate, even if no one is subscribed to the event.
For instance, if the type has 15 events, then when you create an instance of the object, it will have 15 pointers to delegates.  Most of the events will be null.
Now, if we change the type to use add and remove and implement the add and remove like so:
public EventHandler Click
{
   add
   {
       eventList.Add(ClickKey, value);
   }
  remove
   {
       eventList.Remove(ClickKey, value);
   }
}

Where eventList is an EventHandlerList, then your type only needs one reference to track all of it&#039;s events instead of 15.  If an event is never subscribed to, then it creates no overhead.  While the field approach would always require a null pointer.

Btw, add and remove aren&#039;t the only accessors supported by the .net framework.  C++ allows you to also define the raise accessor, but it&#039;s not allowed in C#.</description>
		<content:encoded><![CDATA[<p>Actually, the most common reason to implement an add &amp; remove on an event is for memory consumption.  For instance, let&#8217;s say you have a type which has a large number of events.  If those events are defined with just a public event field, then the type has to allocate store for each delegate, even if no one is subscribed to the event.<br />
For instance, if the type has 15 events, then when you create an instance of the object, it will have 15 pointers to delegates.  Most of the events will be null.<br />
Now, if we change the type to use add and remove and implement the add and remove like so:<br />
public EventHandler Click<br />
{<br />
   add<br />
   {<br />
       eventList.Add(ClickKey, value);<br />
   }<br />
  remove<br />
   {<br />
       eventList.Remove(ClickKey, value);<br />
   }<br />
}</p>
<p>Where eventList is an EventHandlerList, then your type only needs one reference to track all of it&#8217;s events instead of 15.  If an event is never subscribed to, then it creates no overhead.  While the field approach would always require a null pointer.</p>
<p>Btw, add and remove aren&#8217;t the only accessors supported by the .net framework.  C++ allows you to also define the raise accessor, but it&#8217;s not allowed in C#.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: jgr4</title>
		<link>http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/comment-page-1/#comment-216</link>
		<dc:creator>jgr4</dc:creator>
		<pubDate>Thu, 15 Jan 2009 22:23:03 +0000</pubDate>
		<guid isPermaLink="false">http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/#comment-216</guid>
		<description>Thanks for the post. One usage is for debugging. I couldn&#039;t figure out where handlers were getting added and why there seemed to be to many. This technique allows you to put a breakpoint or a Debug.WriteLine in the add {}.</description>
		<content:encoded><![CDATA[<p>Thanks for the post. One usage is for debugging. I couldn&#8217;t figure out where handlers were getting added and why there seemed to be to many. This technique allows you to put a breakpoint or a Debug.WriteLine in the add {}.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Cosmin Onea</title>
		<link>http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/comment-page-1/#comment-210</link>
		<dc:creator>Cosmin Onea</dc:creator>
		<pubDate>Thu, 11 Dec 2008 00:29:20 +0000</pubDate>
		<guid isPermaLink="false">http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/#comment-210</guid>
		<description>http://www.cosminonea.net/2008/12/10/Subsonic30AndAPossibleSerializationProblem.aspx

This may be one possible good usage.</description>
		<content:encoded><![CDATA[<p><a href="http://www.cosminonea.net/2008/12/10/Subsonic30AndAPossibleSerializationProblem.aspx" rel="nofollow">http://www.cosminonea.net/2008/12/10/Subsonic30AndAPossibleSerializationProblem.aspx</a></p>
<p>This may be one possible good usage.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Hank Hatch</title>
		<link>http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/comment-page-1/#comment-203</link>
		<dc:creator>Hank Hatch</dc:creator>
		<pubDate>Mon, 03 Nov 2008 17:46:03 +0000</pubDate>
		<guid isPermaLink="false">http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/#comment-203</guid>
		<description>Also it is more of a direct wrap to do it like this -&gt;

        private StateMachineEventHandler canTransition;
        public event StateMachineEventHandler CanTranistion
        {
            add { this.canTransition += value; }
            remove { this.canTransition -= value; }
        }

which is pretty darn simple considering the power it can give you.</description>
		<content:encoded><![CDATA[<p>Also it is more of a direct wrap to do it like this -&gt;</p>
<p>        private StateMachineEventHandler canTransition;<br />
        public event StateMachineEventHandler CanTranistion<br />
        {<br />
            add { this.canTransition += value; }<br />
            remove { this.canTransition -= value; }<br />
        }</p>
<p>which is pretty darn simple considering the power it can give you.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Hank Hatch</title>
		<link>http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/comment-page-1/#comment-202</link>
		<dc:creator>Hank Hatch</dc:creator>
		<pubDate>Mon, 03 Nov 2008 17:34:51 +0000</pubDate>
		<guid isPermaLink="false">http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/#comment-202</guid>
		<description>The main purpose of this is really the following:
In C++ we basically had to manage our own lists of function pointers (callbacks) in order to provide for notifications.
In visual basic we had events built in.
So in order to make events easier and more modern and acceptable (probably to convert more VB programmers into C# programmers) events had to be a language feature.
Type safe function pointers (delegates) are used to make this possible.
Built into delegates have invokation lists.
Enter managed code and garbage collection.
Enter you as a component developer.
If you do not declare your delegate as a private member of your class then YOU cannot access it&#039;s invokation list.
If you only declare the event public (and therefore do not have a property) then you are limited by the compiler to the access of that field.
The documentation states that the keyword event limits access to the delegate to using the binary += and -+ operators.
So long story short is this.
Considering the keyword &quot;event&quot; exists is NO excuse to be irrisponsible in coding and lazy.
Not using this pattern is somewhat the same as being irrisponsible with your pointers in a non managed environment.
It is similar to NOT calling delete or not creating a &quot;smart pointer&quot; type situation where you bind delete, removing of a reference counter, and the setting to null all in one step.
What I am saying is this.
If you are going to code a component that offers many events and design that component so that it is going to be heavily used then you don&#039;t want to subject every single one of you clients to surviving generation 1 garbage collection.
If you offer an event and you have subscribers even if this goes out of scope your hidden non accessible invokation lists all still have references to you old clients.  They will then NOT be released from garbage collection as soon as they could be.  If you combine structures like this in algorithms that utilize a high number of objects or lots of stack space then you are coding yourself into the situation that you do not have the EXPLICIT unbinding of objects in object graphs so that your component can be used in many situations.

Basically this is another way to say it.  If your component offers events it is better to also offer IDisposable so that the client code can decide how things are handled.  Create a private delegate.  Create a public event so clients can subscribe to the notification with the += and -+ operators they are used to.  But now VERY important -&gt; in your Dispose enumerate the private delegates invokation list and remove the references to the clients.  This is a &quot;TearDown&quot; and the same thing WAS necessary in VB 6 for certain situations (pointers to parent objects in collections as an example with a COM reference counting systems).

This way you can better control and increase the number of objects that will be freed during a lower generation of garbage collection.

Remember just because it is C# and managed code DOES NOT mean you cannot have a memory leak.  If you want to expand an object oriented language with &quot;out-going calls&quot; or &quot;events&quot; which is basically implemented with circular referencing then be aware that just because something was automated for you DOES NOT mean you can&#039;t get in trouble.

Keep the private delegate for anytime you feel you need to control the members of the invokation list.  I have been stressing just the garbage collection and memory leak but there are other patterns.  Use it when you want to dump the list and require new subscriptions from within a server or singleton periodically.  Often templating out this pattern without the dispose is my preference NOT because I want to show people what I know but because I want to somewhat document that depending on how my object is used a refactor should take place which includes some code in here.  That is not obvious with the use of the public event field.</description>
		<content:encoded><![CDATA[<p>The main purpose of this is really the following:<br />
In C++ we basically had to manage our own lists of function pointers (callbacks) in order to provide for notifications.<br />
In visual basic we had events built in.<br />
So in order to make events easier and more modern and acceptable (probably to convert more VB programmers into C# programmers) events had to be a language feature.<br />
Type safe function pointers (delegates) are used to make this possible.<br />
Built into delegates have invokation lists.<br />
Enter managed code and garbage collection.<br />
Enter you as a component developer.<br />
If you do not declare your delegate as a private member of your class then YOU cannot access it&#8217;s invokation list.<br />
If you only declare the event public (and therefore do not have a property) then you are limited by the compiler to the access of that field.<br />
The documentation states that the keyword event limits access to the delegate to using the binary += and -+ operators.<br />
So long story short is this.<br />
Considering the keyword &#8220;event&#8221; exists is NO excuse to be irrisponsible in coding and lazy.<br />
Not using this pattern is somewhat the same as being irrisponsible with your pointers in a non managed environment.<br />
It is similar to NOT calling delete or not creating a &#8220;smart pointer&#8221; type situation where you bind delete, removing of a reference counter, and the setting to null all in one step.<br />
What I am saying is this.<br />
If you are going to code a component that offers many events and design that component so that it is going to be heavily used then you don&#8217;t want to subject every single one of you clients to surviving generation 1 garbage collection.<br />
If you offer an event and you have subscribers even if this goes out of scope your hidden non accessible invokation lists all still have references to you old clients.  They will then NOT be released from garbage collection as soon as they could be.  If you combine structures like this in algorithms that utilize a high number of objects or lots of stack space then you are coding yourself into the situation that you do not have the EXPLICIT unbinding of objects in object graphs so that your component can be used in many situations.</p>
<p>Basically this is another way to say it.  If your component offers events it is better to also offer IDisposable so that the client code can decide how things are handled.  Create a private delegate.  Create a public event so clients can subscribe to the notification with the += and -+ operators they are used to.  But now VERY important -&gt; in your Dispose enumerate the private delegates invokation list and remove the references to the clients.  This is a &#8220;TearDown&#8221; and the same thing WAS necessary in VB 6 for certain situations (pointers to parent objects in collections as an example with a COM reference counting systems).</p>
<p>This way you can better control and increase the number of objects that will be freed during a lower generation of garbage collection.</p>
<p>Remember just because it is C# and managed code DOES NOT mean you cannot have a memory leak.  If you want to expand an object oriented language with &#8220;out-going calls&#8221; or &#8220;events&#8221; which is basically implemented with circular referencing then be aware that just because something was automated for you DOES NOT mean you can&#8217;t get in trouble.</p>
<p>Keep the private delegate for anytime you feel you need to control the members of the invokation list.  I have been stressing just the garbage collection and memory leak but there are other patterns.  Use it when you want to dump the list and require new subscriptions from within a server or singleton periodically.  Often templating out this pattern without the dispose is my preference NOT because I want to show people what I know but because I want to somewhat document that depending on how my object is used a refactor should take place which includes some code in here.  That is not obvious with the use of the public event field.</p>
]]></content:encoded>
	</item>
</channel>
</rss>

