<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>C#</title>
        <link>http://geekswithblogs.net/UlteriorMotiveLounge/category/9126.aspx</link>
        <description>Discussion of C# development.</description>
        <language>en-US</language>
        <copyright>Martin L. Shoemaker</copyright>
        <managingEditor>Martin@TheUMLGuy.com</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <item>
            <title>Lessons in porting</title>
            <link>http://geekswithblogs.net/UlteriorMotiveLounge/archive/2008/11/15/lessons-in-porting.aspx</link>
            <description>&lt;div class="post"&gt;At a client's request, I've been porting my Tablet PC labs to VB.NET. In the process, I've learned some lessons that might be helpful to others who have to make this sort of a port. This is strictly programmer geek stuff, so I'm hiding it. The rest of you may prefer to &lt;a href="http://mfrost.typepad.com/cute_overload/2006/06/is_there_room_e.html"&gt;look at the cute baby llama&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="trigger" id="sheoq7lab3.6b" style="DISPLAY: none"&gt;&lt;a onclick="document.getElementById('heoq7lab3.6b').style.display = 'block'; document.getElementById('sheoq7lab3.6b').style.display = 'none'; return false;" href="http://tabletumlnews.powerblogs.com/archives/archive_2006_06.shtml#"&gt;I'm ready for programmer geek stuff...&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class="hidden" id="heoq7lab3.6b" style="DISPLAY: block"&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Note:&lt;/strong&gt; In no way is this intended as a slam against VB.NET. Anything I can do with C#, I can do with VB.NET, and vice versa. It's simply a pair of lessons to keep in mind if you work in both languages.&lt;br /&gt;
&lt;br /&gt;
But before the lessons, let me briefly describe the porting process, since either of these lessons might not have been learned if I had written the VB.NET code from scratch. I started with 200 pages of C# labs (yes, folks, my Tablet PC class is that intensive, and more). Then I built a VB.NET project, recreated the UI elements by hand, pasted in the C# code, and edited the code until it was syntactically correct for VB.NET. And except for these two lessons, it seems to have worked well.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Lesson 1: Divide &amp;lt;&amp;gt; Divide&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
I had a strange bug in the VB.NET version of the labs. In C#, I could scroll the document to the end of the page. In VB.NET, I would get an exception after the scroll passed the half-way point. Digging into the debugger, I found that my scroll bar ranged from 0 to 99; but I was trying to set the scroll bar value to 101. Further investigation led me to discover differences in the behavior of division in the two languages.&lt;br /&gt;
&lt;br /&gt;
Let's look at some C# code first:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;static void Main(string[] args)&lt;br /&gt;
{&lt;br /&gt;
    object result = 51 / 100;&lt;br /&gt;
    Console.WriteLine(result.GetType().Name +&lt;br /&gt;
        " - " + result.ToString());&lt;br /&gt;
}&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
This code divides two integers and stores the result in an &lt;strong&gt;object&lt;/strong&gt;, the .NET base type that all other types derive from. That means that any value can be stores as an object. The code then displays the real type of the object, as well as a string representation of the value of the object. And here's the result:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;Int32 - 0&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
Now here's what &lt;em&gt;seems&lt;/em&gt; like the same VB.NET code. This is exactly what I get by following my copy-and-make-it-compile porting strategy:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;Sub Main()&lt;br /&gt;
&lt;br /&gt;
    Dim result As Object = 51 / 100&lt;br /&gt;
    Console.WriteLine(result.GetType().Name + _&lt;br /&gt;
        " - " + result.ToString())&lt;br /&gt;
&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
And here's the result:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;Double - 0.51&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
This is probably not news to any VB or VB.NET or even just Basic programmers out there; but it's important for porting programmers to keep in mind:&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;In Basic, any numeric divisor or dividend is converted to a Double (i.e., a double-precision floating point value) before the division, and the resulting quotient is a Double.&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Anyone who knows VB.NET will see the obvious error in my port: I should have used the special integer division operator, \:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;Sub Main()&lt;br /&gt;
&lt;br /&gt;
    Dim result As Object = 51 \ 100&lt;br /&gt;
    Console.WriteLine(result.GetType().Name + _&lt;br /&gt;
        " - " + result.ToString())&lt;br /&gt;
&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
And here's the result:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;Int32 - 0&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
The results are exactly the same as we saw with the original C# code.&lt;br /&gt;
&lt;br /&gt;
The problem with this lesson is that it completely undermines my copy-and-make-it-compile porting strategy: the copied division symbol &lt;em&gt;compiles&lt;/em&gt;, but it doesn't yield the same results.&lt;br /&gt;
&lt;br /&gt;
And it gets slightly more complicated yet. Let's modify that C# code:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;static void Main(string[] args)&lt;br /&gt;
{&lt;br /&gt;
    object result = (int)(51.0f / 100.0f);&lt;br /&gt;
    Console.WriteLine(result.GetType().Name +&lt;br /&gt;
        " - " + result.ToString());&lt;br /&gt;
}&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
Here, I &lt;em&gt;know&lt;/em&gt; I'm dividing floating point values; but then I cast back to an int. And here's the result:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;Int32 - 0&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
It's exactly the same as the original, because the final cast truncates the fractional portion.&lt;br /&gt;
&lt;br /&gt;
Now here's the "same" code, VB.NET style:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;Sub Main()&lt;br /&gt;
&lt;br /&gt;
    Dim result As Object = CInt(51.0f / 100.0f)&lt;br /&gt;
    Console.WriteLine(result.GetType().Name + _&lt;br /&gt;
        " - " + result.ToString())&lt;br /&gt;
&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
And here's the result:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;Int32 - 1&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
The result is an integer, just like in C#; but instead of the remainder being truncated, it's rounded, either up or down. (And then, just to offend mathematical norms, a precise value of 0.5 will round &lt;em&gt;down&lt;/em&gt;.)&lt;br /&gt;
&lt;br /&gt;
So I could see that the division results needed to be converted; but I didn't see that as they were converted, they were rounding.&lt;br /&gt;
&lt;br /&gt;
Keep in mind as you port: Divide != Divide.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Lesson 2: Name &amp;lt;&amp;gt; Name&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Inside a C# Form (i.e., inherited from System.Windows.Forms.Form), I wrote code that looked like this:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;private void OpenDrawing()&lt;br /&gt;
{&lt;br /&gt;
    if (dlgOpen.ShowDialog(this) == DialogResult.OK)&lt;br /&gt;
    {&lt;br /&gt;
        OpenDrawing(dlgOpen.FileName);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
Ported to a VB.NET Form, the code looked like this:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;Private Sub OpenDrawing()&lt;br /&gt;
    If (dlgOpen.ShowDialog(Me) = &lt;strong&gt;DialogResult.OK&lt;/strong&gt;) Then&lt;br /&gt;
        OpenDrawing(dlgOpen.FileName)&lt;br /&gt;
    End If&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
Both versions compiled. Both versions ran correctly. But when I compiled the VB.NET version, I got this warning on the highlighted code:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
Access of shared member, constant member, enum member or nested type through an instance; qualifying expression will not be evaluated.&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
After a little thought, I remembered that System.Windows.Forms.Form has a property of type DialogResult that is also &lt;em&gt;called&lt;/em&gt; DialogResult &lt;em&gt;and&lt;/em&gt; that the return type from ShowDialog is &lt;em&gt;also&lt;/em&gt; of type DialogResult.&lt;br /&gt;
&lt;br /&gt;
Now you might question the wisdom of using the same name for a property and its type. Heck, I've done it a lot myself, but now &lt;em&gt;I'm&lt;/em&gt; questioning the wisdom. Because it appears that VB.NET and C# have different rules for resolving that name: C# looks to the name first, while VB.NET looks to the property first. Now as it happens, VB.NET sees the property used as a qualifier to access a value within the type, sees the qualifier as superfluous, issues a warning, and just uses the type. So the end result is the same; but the VB.NET programmer gets a confusing or possible scary warning message.&lt;br /&gt;
&lt;br /&gt;
Now there's a very easy way to avoid that message: simply be explicit. Here's a modified version:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;Private Sub OpenDrawing()&lt;br /&gt;
    If (dlgOpen.ShowDialog(Me) = &lt;strong&gt;System.Windows.Forms.Form.DialogResult.OK&lt;/strong&gt;) Then&lt;br /&gt;
        OpenDrawing(dlgOpen.FileName)&lt;br /&gt;
    End If&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
When you explicitly qualify the type, VB.NET won't be confused about what you mean, and the warning goes away.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="trigger"&gt;&lt;a onclick="document.getElementById('sheoq7lab3.6b').style.display = 'block';document.getElementById('heoq7lab3.6b').style.display = 'none'; return false;" href="http://tabletumlnews.powerblogs.com/archives/archive_2006_06.shtml#"&gt;Too geeky for me! Make it go away!&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=127074"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=127074" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/UlteriorMotiveLounge/aggbug/127074.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Martin L. Shoemaker</dc:creator>
            <guid>http://geekswithblogs.net/UlteriorMotiveLounge/archive/2008/11/15/lessons-in-porting.aspx</guid>
            <pubDate>Sat, 15 Nov 2008 22:13:33 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/UlteriorMotiveLounge/comments/127074.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/UlteriorMotiveLounge/archive/2008/11/15/lessons-in-porting.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/UlteriorMotiveLounge/comments/commentRss/127074.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Richard Hale Shaw says, "Put up or shut up!"</title>
            <link>http://geekswithblogs.net/UlteriorMotiveLounge/archive/2008/11/15/richard-hale-shaw-says-put-up-or-shut-up.aspx</link>
            <description>&lt;div class="post"&gt;Well, maybe that's not &lt;em&gt;exactly&lt;/em&gt; how he put it; but he referenced a post where I wrote:&lt;br /&gt;
&lt;blockquote&gt;Richard Hale Shaw makes &lt;a href="http://www.richardhaleshawgroup.com/RHSGroup/Community/blogs/richard_hale_shaws_blog/archive/2005/10/06/177.aspx"&gt;an interesting argument against the C# &lt;strong&gt;using&lt;/strong&gt; statement&lt;/a&gt; (not the &lt;strong&gt;using&lt;/strong&gt; directive; and thank you, C# team, for that bit of confusing language). I disagree with him; but it will take time and sleep before I can fully explain why. The short preview: he says you can't force people to use your class correctly; I say I can, and I'll show you how, soon.&lt;/blockquote&gt;And he writes:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;Always wondered what you had in mind.&lt;/blockquote&gt;Well, he's right: it's way past time I finished this thought!&lt;br /&gt;
&lt;br /&gt;
Fair warning: the rest of this post is code, code, code! Instead of reading further, you non-programmers may instead prefer to &lt;a href="http://mfrost.typepad.com/cute_overload/2006/01/holy_interspeci.html"&gt;go look at the cute squirrel&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
&lt;br /&gt;
OK, now that only geeks and masochists are left, let's review the highlights of Richard's argument for why the C# &lt;strong&gt;using&lt;/strong&gt; statement isn't very helpful. Here are some excerpts and comments:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;And more and more developers are discovering the third variation or &lt;strong&gt;using&lt;/strong&gt; statement: using &lt;strong&gt;using&lt;/strong&gt; for early disposal:&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;using(MyObj obj = new MyObj())&lt;br /&gt;
{&lt;br /&gt;
&lt;blockquote&gt;obj.DoStuff();&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
}&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
When the C# compiler encounters this use of &lt;strong&gt;using&lt;/strong&gt;, it will only compile correctly if the target — in this case, obj — implements IDisposable (and therefore, IDisposable.Dispose).&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
Actually, I recently discovered this isn't &lt;em&gt;quite&lt;/em&gt; true. The class of the object need not implement IDisposable, &lt;em&gt;as long as one of its ancestor classes does&lt;/em&gt;. As long as the object may be cast to an IDisposable, it doesn't matter whether that's through the ultimate class or some ancestor class. Thus, for instance, a StreamWriter object can be used in a &lt;strong&gt;using&lt;/strong&gt; statement, even though StreamWriter doesn't implement IDisposable. Why? Because StreamWriter inherits from TextWriter, and TextWriter &lt;em&gt;does&lt;/em&gt; implement IDisposable. For a while, I would diligently look up each class before using it in a &lt;strong&gt;using&lt;/strong&gt; statement, checking to see if it implements IDisposable. Now I've decided that, when in doubt, I'll just stick it in a &lt;strong&gt;using&lt;/strong&gt; statement, and let the compiler tell me if there's no IDisposable to be found. If it does any work with files or ports or graphics resources, I just assume IDisposable until proven otherwise.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="trigger" id="sheijsmuwk.71"&gt;(&lt;a onclick="document.getElementById('heijsmuwk.71').style.display = 'block'; document.getElementById('sheijsmuwk.71').style.display = 'none'; return false;" href="http://tabletumlnews.powerblogs.com/archives/archive_2006_01.shtml#"&gt;And for an example of "proven otherwise"...&lt;/a&gt;)&lt;/div&gt;
&lt;br /&gt;
&lt;div class="hidden" id="heijsmuwk.71" style="DISPLAY: none"&gt;&lt;br /&gt;
Consider GraphicsState, the class that saves the state of a Graphics object so that you can restore it later. To me, this class all but &lt;strong&gt;screams&lt;/strong&gt; to be used like this:&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;font face="Courier New"&gt;Graphics g; // This probably came in as some parameter somewhere.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
using (GraphicsState gs = g.Save() ) // NOTE: This will not compile!&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;// Do stuff that changes g, counting on gs&lt;br /&gt;
// to clean it all up at the end of the using&lt;br /&gt;
// statement.&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
But nope, that doesn't work: GraphicsState doesn't implement IDisposable. The best you can do is something like this:&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;Graphics g; // This probably came in as some parameter somewhere.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
GraphicsState gs = g.Save();&lt;br /&gt;
try&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;font face="Courier New"&gt;// Do stuff that changes g. You'll clean&lt;br /&gt;
// it up later.&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
finally&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;// And THIS is later.&lt;br /&gt;
g.Restore(gs);&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Of course, there's always this workaround:&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;// Can't inherit from GraphicsState. It's marked sealed.&lt;br /&gt;
// Best you can do is get one from a parameter.&lt;br /&gt;
// NOTE: This class is ONLY AN EXAMPLE. It needs a LOT&lt;br /&gt;
// more work to be production-ready.&lt;br /&gt;
class DisposableState : IDisposable&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;private GraphicsState mState = null;&lt;br /&gt;
private Graphics mGraphics = null;&lt;br /&gt;
&lt;br /&gt;
public DisposableState(Graphics g)&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;mGraphics = g;&lt;br /&gt;
mState = g.Save();&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;br /&gt;
// NOTE: This method is PARTICULARLY lacking in&lt;br /&gt;
// important design features, as Richard discussed in&lt;br /&gt;
// his post, and as Bill Wagner explains in great&lt;br /&gt;
// detail in &lt;/font&gt;&lt;a href="http://www.amazon.com/exec/obidos/tg/detail/-/0321245660/qid=1137478273/sr=2-1/ref=pd_bbs_b_2_1/104-7349866-5589513?v=glance&amp;amp;s=books"&gt;&lt;font face="Courier New"&gt;Effective C#&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier New"&gt;.&lt;br /&gt;
public void Dispose()&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;if ( ( mGraphics != null ) &amp;amp;&amp;amp; ( mState != null ) )&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;mGraphics.Restore( mState );&lt;br /&gt;
mGraphics = null;&lt;br /&gt;
mState = null;&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Graphics g; // This probably came in as some parameter somewhere.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
using (DisposableState ds = new DisposableState( g ))&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;// And NOW you can do stuff that changes g,&lt;br /&gt;
// secure in the knowledge that ds will clean&lt;br /&gt;
// it all up at the end of the using statement.&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
This still needs some design thought in all sorts of ways, particularly in regards to what happens if someone doesn't dispose of the DisposableState. But then again, that's back to the point of this post: we're going to make it really hard to &lt;em&gt;not&lt;/em&gt; dispose of a disposable item.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="trigger"&gt;(&lt;a onclick="document.getElementById('sheijsmuwk.71').style.display = 'block';document.getElementById('heijsmuwk.71').style.display = 'none'; return false;" href="http://tabletumlnews.powerblogs.com/archives/archive_2006_01.shtml#"&gt;Hide this example.&lt;/a&gt;)&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Continuing with excerpts from Richard's post:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
In the resulting IL, the compiler takes what you put inside the block (or if you didn't use a block, the single statement that would follow the &lt;strong&gt;using&lt;/strong&gt; statement) with a try...finally block:&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;font face="Courier New"&gt;IL_0000: newobj instance void ObjectDisposal.MyObj::.ctor()&lt;br /&gt;
IL_0005: stloc.0&lt;br /&gt;
.try&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;IL_0006: ldloc.0&lt;br /&gt;
IL_0007: callvirt instance void ObjectDisposal.MyObj::DoStuff()&lt;br /&gt;
IL_000c: leave.s IL_0018&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;} // end .try&lt;br /&gt;
finally&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;IL_000e: ldloc.0&lt;br /&gt;
IL_000f: brfalse.s IL_0017&lt;br /&gt;
IL_0011: ldloc.0&lt;br /&gt;
IL_0012: callvirt instance void [mscorlib]System.IDisposable::Dispose()&lt;br /&gt;
IL_0017: endfinally&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;} // end handler&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
Now here's a difference between Richard and me: he loves IL code, while I'd rather not look at it unless I have to. What he's saying, in plain C#, is that the &lt;strong&gt;using&lt;/strong&gt; block above is equivalent to this:&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;MyObj obj = new MyObj();&lt;br /&gt;
try&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;obj.DoStuff();&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;} // end .try&lt;br /&gt;
finally&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;obj.Dispose();&lt;br /&gt;
endfinally&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;} // end handler&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
There, isn't that a lot more comprehensible all all that nasty IL code?&lt;br /&gt;
&lt;br /&gt;
Unfortunately, even though you'll often see people "translate" that &lt;strong&gt;using&lt;/strong&gt; block that way, it's also &lt;em&gt;wrong&lt;/em&gt;. Foreshadowing one of Richard's later points, it's important to note that in this &lt;strong&gt;using&lt;/strong&gt; block...&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;font face="Courier New"&gt;using(MyObj obj = new MyObj())&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;font face="Courier New"&gt;obj.DoStuff();&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;...the object obj is out of scope at the end of the block, and may no longer be referenced.&lt;/em&gt; Because it was declared within the &lt;strong&gt;using&lt;/strong&gt; statement, its scope ends when the &lt;strong&gt;using&lt;/strong&gt; statement ends — which means, in fact, the closing curly brace. So a truly proper C# "translation" of that &lt;strong&gt;using&lt;/strong&gt; block would look like this:&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;font face="Courier New"&gt;MyObj obj = new MyObj();&lt;br /&gt;
try&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;font face="Courier New"&gt;obj.DoStuff();&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;font face="Courier New"&gt;} // end .try&lt;br /&gt;
finally&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;font face="Courier New"&gt;obj.Dispose();&lt;br /&gt;
endfinally&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;font face="Courier New"&gt;} // end handler&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Note the extra curly braces needed to define a scope block that encompasses obj.&lt;br /&gt;
&lt;br /&gt;
Continuing again with excerpts from Richard's post:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
But there's nothing automatic about &lt;strong&gt;using&lt;/strong&gt; statements: the client or user of the class has to add them. That's no more automatic than manually calling Dispose yourself.&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
And here's where I'm going to differ with Richard: while we can't make &lt;strong&gt;using&lt;/strong&gt; automatic, we can add code that makes it extremely visible when someone has failed to dispose of resources properly. We can't force client code to be written well, but we can nudge really strongly. I'll explain the details at the end of this post.&lt;br /&gt;
&lt;br /&gt;
There's also a way in which &lt;strong&gt;using&lt;/strong&gt; is, if not automatic, then easier. For one thing, it's just plain less typing and less formatting than a &lt;strong&gt;try&lt;/strong&gt;/&lt;strong&gt;finally&lt;/strong&gt;. I tell my students that I'm the laziest programmer on the planet, and I want to make my job as easy as possible. And I encourage them to adopt the same attitude: they should think, and the tool should work, not the other way around. Plus &lt;strong&gt;using&lt;/strong&gt; is almost always a good habit if not misused (as Richard discusses below); and I like to program good habits into my fingers, so that good code just sorta naturally flows out. Almost automatic, you might say.&lt;br /&gt;
&lt;br /&gt;
I would also contend (since I can't help being pedantic) that there's something &lt;em&gt;slightly&lt;/em&gt; automatic about &lt;strong&gt;using&lt;/strong&gt;: it provides that implicit scope block described above, which lets the compiler tell you when someone tries to access the disposed object out of scope. Of course, that will lead into a problem that Richard very properly describes farther down:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;And if the syntax above was the only way you could use &lt;strong&gt;using&lt;/strong&gt; (where the target is instantiated in the parameter list), I'd have no objection to it whatsover. But the fact is that the target can be instantiated anytime prior to the &lt;strong&gt;using&lt;/strong&gt; statement as well:&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;font face="Courier New"&gt;MyObj obj = new MyObj();&lt;br /&gt;
...&lt;br /&gt;
using(obj)&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;font face="Courier New"&gt;obj.DoStuff();&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
My problem with this is that you could still have what appear to be valid calls to methods/properties on what is now a disposed object:&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;font face="Courier New"&gt;MyObj obj = new MyObj();&lt;br /&gt;
...&lt;br /&gt;
using(obj)&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;font face="Courier New"&gt;obj.DoStuff();&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;font face="Courier New"&gt;}&lt;br /&gt;
...&lt;br /&gt;
obj.DoStuff();&lt;br /&gt;
&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Oh, and the compiler is NOT going to help you here.&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
Yep. Absolutely. This is a real problem, and you have to tread cautiously. I have run into a case now and then where I wanted to use Dispose on a previously allocated object. It's uncommon, but not necessarily wrong.&lt;br /&gt;
&lt;br /&gt;
We should always prefer compiler-automatic to catch problems whenever possible. Relying on people to get it right can get us into trouble, because people are, well, people. They make mistakes. As Richard wrote:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;The Dispose Pattern says that once Dispose has been called, subsequent calls to Dispose should be benign (do nothing) but subsequent calls to any other public operation should throw an ObjectDisposedException. So now we have a case where a developer thinks they've automated (or semi-automated) resource disposal, but could use the object again as well.&lt;br /&gt;
&lt;br /&gt;
It's just too confusing: there's no way to know that the object has been disposed unless you know what the &lt;strong&gt;using&lt;/strong&gt; statement does internally. If you know that, of course, you'd make it a Best Practice to avoid using &lt;strong&gt;using&lt;/strong&gt;, or avoid using &lt;strong&gt;using&lt;/strong&gt; without instantiating the target in the parameter list. I know this. You know this if you've attended one of my classes, or someone else's class, or read it in a book or figured it out yourself.&lt;br /&gt;
&lt;br /&gt;
But how do you count on someone else — who's now charged with modifying and maintaining this code base — knowing it? You can't and you don't.&lt;/blockquote&gt;To me, Richard hasn't diagnosed a problem with &lt;strong&gt;using&lt;/strong&gt;; he has diagnosed a problem with IDisposable, and with .NET, and in fact with resource management in general in a memory-managed environment: even though the environment is cleaning up discarded memory for you, you can't guarantee people will free up their non-memory resources when they're done with them.&lt;br /&gt;
&lt;br /&gt;
In other words, he has detected the Return of the Sandwich.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="trigger" id="sheijwfo9y.c0"&gt;(&lt;a onclick="document.getElementById('heijwfo9y.c0').style.display = 'block'; document.getElementById('sheijwfo9y.c0').style.display = 'none'; return false;" href="http://tabletumlnews.powerblogs.com/archives/archive_2006_01.shtml#"&gt;Cue up ominous music, and click here if you need a refresher on the Sandwich Pattern, the Construct/Destruct Pattern, and the whole rationale behind memory management and garbage collection.&lt;/a&gt;)&lt;/div&gt;
&lt;br /&gt;
&lt;div class="hidden" id="heijwfo9y.c0" style="DISPLAY: none"&gt;Back in the bad old days of Windows 3.0 programming, those of us schooled by &lt;a href="http://www.amazon.com/exec/obidos/tg/detail/-/0735613702/qid=1137482083/sr=2-2/ref=pd_bbs_b_2_2/104-7349866-5589513?v=glance&amp;amp;s=books"&gt;The Great One&lt;/a&gt; had to burn into our brains one overriding design limit: 64K. For you young'uns, a K is a kilobyte of memory. Yes, as in 1,024 bytes. Yes, 64K is probably less memory than you have in a cheap cell phone today. But that was all we had back then for certain types of data. How much room was there for &lt;em&gt;all&lt;/em&gt; of the window information for &lt;em&gt;all&lt;/em&gt; apps running simultaneously under Win3.0? 64K. How much room was there for &lt;em&gt;all&lt;/em&gt; the other drawing stuff — fonts, pens, brushes, regions, etc. — for &lt;em&gt;all&lt;/em&gt; apps running simultaneously under Win3.0? Another 64K. I'm not talking 64K per app; I'm talking 64K for the whole system. If my app grabbed 63.99K of either the window heap or the resource heap, your app was probably going to fail when it tried to display itself; and unless you wrote your code to handle that failure gracefully (and tested that failure), my &lt;em&gt;&lt;/em&gt;sloppy code could make &lt;em&gt;your&lt;/em&gt; code crash in a most ugly fashion. A carelessly written app could sometimes crash all of Windows with less than a score of mouse clicks.&lt;br /&gt;
&lt;br /&gt;
So how did one write code carefully? With the Sandwich Pattern:&lt;br /&gt;
&lt;br /&gt;
BREAD: Allocate some resource.&lt;br /&gt;
MEAT: Use the resource.&lt;br /&gt;
BREAD: Free the resource.&lt;br /&gt;
&lt;br /&gt;
All good Win 3.0 code was full of Sandwiches. You need to print, and you want to use a special font?&lt;br /&gt;
&lt;br /&gt;
BREAD: Allocate the font.&lt;br /&gt;
MEAT: Print with the font.&lt;br /&gt;
BREAD: Free the font.&lt;br /&gt;
&lt;br /&gt;
There were lots of variations of Sandwiches, and Sandwiches within Sandwiches; but it all came down to the Sandwich Pattern.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, not everyone programming learned from The Great One. Some learned from following examples in magazines. Some learned from watching what others did. Some learned by visiting BBSes and chat rooms, and just generally picking up folklore. Some learned by trial and error. And even some who learned from The Great One didn't really get the importance of resource management.&lt;br /&gt;
&lt;br /&gt;
And so some folks simply didn't use Sandwiches. And thus were many a user's day ruined when some Windows app crashed, or even Windows itself; and often the culprit app was impossible to determine, because the app that crashed was the one that couldn't get resources, &lt;em&gt;not&lt;/em&gt; the one that refused to give them up.&lt;br /&gt;
&lt;br /&gt;
Now resource management and the Sandwich Pattern are by no means unique to Win 3.0, or even to Windows at all. (Win 3.0 just happened to be extraordinarily vulnerable to the problem.) So one of the important design elements of the C++ language was constructors and destructors: a constructor gets called when an obect gets created; and a destructor gets called when it gets destroyed. In a sense, they are the Sandwich Pattern built into the object, with the constructor and destructor serving as the bread. And this was very much by design: if you grabbed all your resources during the constructor and freed them in your destructor, then the code that used your object never had to worry about — or even know&lt;em&gt;&lt;/em&gt; about — your resource management. If you wrote a library for managing a resource, you could count on destructors to free up resources.&lt;br /&gt;
&lt;br /&gt;
Except... Well, except there are still sloppy humans writing code; and they still sometimes make mistakes. If they created an object locally, the compiler would automate destructing the object when it went out of scope. But if they created the object on the heap, then it only got destroyed when they intentionally destroyed it. Like the Sandwich Pattern, the Construct/Destruct Pattern only works when you actually follow it.&lt;br /&gt;
&lt;br /&gt;
Now as it happens, one of the most commonly lost resources in this situation is memory itself; and as it also happens, that's one that can be managed well automatically, with a good environment. And so that's what managed environments like .NET and Java typically do: they keep track of objects, and get rid of them automatically when they're no longer used.&lt;br /&gt;
&lt;br /&gt;
And then .NET lets you &lt;em&gt;almost&lt;/em&gt; have the Construct/Destruct Pattern via Finalizers: you can clean up any final resources in the finalizer. Of course, that's probably too late, but at least you tried.&lt;br /&gt;
&lt;br /&gt;
And .NET also lets you &lt;em&gt;almost&lt;/em&gt; have the Sandwich Pattern via the Dispose Pattern; but as Richard has correctly pointed out, we're back to a world where the Sandwich only works if everyone knows — and remembers — to use it.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="trigger"&gt;(&lt;a onclick="document.getElementById('sheijwfo9y.c0').style.display = 'block';document.getElementById('heijwfo9y.c0').style.display = 'none'; return false;" href="http://tabletumlnews.powerblogs.com/archives/archive_2006_01.shtml#"&gt;Enough with the Sandwiches already, huh?&lt;/a&gt;)&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
So if the Sandwich only works if everyone knows — and remembers — to use it, that to me is not a &lt;strong&gt;using&lt;/strong&gt; problem: &lt;strong&gt;using&lt;/strong&gt; is just a particular form of the Dispose Pattern, which is a specialized form of the Sandwich Pattern, which relies on fallible humans. The problem is rather that sometimes people don't clean up, whether they're using &lt;strong&gt;using&lt;/strong&gt; or &lt;strong&gt;try&lt;/strong&gt;/&lt;strong&gt;finally&lt;/strong&gt; or whatever. And there's just no way for the compiler to detect that. Now the runtime environment can catch it, because things will fail; but when it does, the results are usually really ugly. We're not back in the days of the 64K limit, and it's pretty hard for an app to crash another app these days; but a poorly performing app can certainly drag down the whole system.&lt;br /&gt;
&lt;br /&gt;
But even worse is that often things &lt;em&gt;won't&lt;/em&gt; fail. On your testing platform, the sloppy code never happens to hit a limit, so you never notice the problem until you ship. And then, of course, your customers find it. Or maybe your testers can tell that something's wrong, because the system starts misbehaving; but they can't diagnose what went wrong. In some ways, it's back to the bad old Win3.0 days: the problem doesn't pop up with the resources that haven't been freed; it pops up in other places, where requests for new resources fail, and then code crashes when it can't get those resources. (Yes, good code should be written to test for a failure to get a resource, and to fail gracefully in response. Wanna bet on how many programs actually do that?)&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
&lt;br /&gt;
So it seemed to me that what we really needed was a way to detect and report undisposed objects. And with a little thought, I realized I could do just that. The result is the class I call MustDispose. Here's the code, all in one chunk. After it's done, I'll dissect it for the important parts.&lt;br /&gt;
&lt;br /&gt;
&lt;table width="60%" border="2" color="#FFFFFF"&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;////////////////////////////////////////////////////////////////////////&lt;br /&gt;
            // Class MustDispose&lt;br /&gt;
            // Copyright (c) 2006 by Martin L. Shoemaker, The Tablet UML Company&lt;br /&gt;
            // Permission is granted to reuse this code within any project, in whole&lt;br /&gt;
            // or in part or in altered form, as long as this copyright statement&lt;br /&gt;
            // is included along with any portion or modification of this code or&lt;br /&gt;
            // of any work derived from this code.&lt;br /&gt;
            ////////////////////////////////////////////////////////////////////////&lt;br /&gt;
            &lt;br /&gt;
            // Using the following namespace.&lt;br /&gt;
            using System;&lt;br /&gt;
            using System.Collections.Generic;&lt;br /&gt;
            using System.Text;&lt;br /&gt;
            using System.Diagnostics;&lt;br /&gt;
            using System.Reflection;&lt;br /&gt;
            &lt;br /&gt;
            // MustDispose is part of the NutsAndBolts library.&lt;br /&gt;
            namespace TabletUMLCompany.NutsAndBolts&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;
            &lt;p&gt;&lt;font face="Courier New"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// Class MustDispose. Use this within an IDisposable implementation&lt;br /&gt;
            /// to ensure that either the object is disposed, or a record is made.&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            /// &amp;lt;example&amp;gt;&lt;br /&gt;
            /// public class DisposableClass : IDisposable&lt;br /&gt;
            /// {&lt;br /&gt;
            /// // The single MustDispose.&lt;br /&gt;
            /// private MustDispose mDispose = new MustDispose( true , true , "This object&lt;br /&gt;
            ///&lt;/font&gt;&lt;font face="Courier New"&gt; holds a brush, which must be released back to Windows when no longer&lt;br /&gt;
            /// needed." );&lt;br /&gt;
            /// &lt;br /&gt;
            /// // The brush that we must release when we're done.&lt;br /&gt;
            /// protected Brush mBrush = null;&lt;br /&gt;
            /// &lt;br /&gt;
            /// // The color.&lt;br /&gt;
            /// private Color mColor = Color.White;&lt;br /&gt;
            /// &lt;br /&gt;
            /// // The color. We will always create a matching brush.&lt;br /&gt;
            /// public Color Color&lt;br /&gt;
            /// {&lt;br /&gt;
            /// get&lt;br /&gt;
            /// {&lt;br /&gt;
            /// // Note how we use the Test method of the MustDispose&lt;br /&gt;
            /// // to verify that we're not disposed yet. It will&lt;br /&gt;
            /// // throw the appropriate exception if we ARE disposed.&lt;br /&gt;
            /// mDispose.Test();&lt;br /&gt;
            /// return mColor;&lt;br /&gt;
            /// }&lt;br /&gt;
            /// set&lt;br /&gt;
            /// {&lt;br /&gt;
            /// // Note how we use the Test method of the MustDispose&lt;br /&gt;
            /// // to verify that we're not disposed yet. It will&lt;br /&gt;
            /// // throw the appropriate exception if we ARE disposed.&lt;br /&gt;
            /// mDispose.Test();&lt;br /&gt;
            /// mColor = value;&lt;br /&gt;
            /// DisposeBrush();&lt;br /&gt;
            /// mBrush = new SolidBrush(mColor);&lt;br /&gt;
            /// }&lt;br /&gt;
            /// }&lt;br /&gt;
            /// &lt;br /&gt;
            /// // Clean up the brush.&lt;br /&gt;
            /// private void DisposeBrush()&lt;br /&gt;
            /// {&lt;br /&gt;
            /// // Note that we DON'T need a call to mDispose.Test() here.&lt;br /&gt;
            /// // Since this is a private method, we're going to assume that&lt;br /&gt;
            /// // we'll only call it when appropriate.&lt;br /&gt;
            /// &lt;br /&gt;
            /// if (mBrush != null)&lt;br /&gt;
            /// {&lt;br /&gt;
            /// mBrush.Dispose();&lt;br /&gt;
            /// mBrush = null;&lt;br /&gt;
            /// }&lt;br /&gt;
            /// }&lt;br /&gt;
            /// &lt;br /&gt;
            /// // The Finalizer. Clean up here, if nowhere else.&lt;br /&gt;
            /// ~DisposableClass()&lt;br /&gt;
            /// {&lt;br /&gt;
            /// // Call the internal Dispose, as per Wagner.&lt;br /&gt;
            /// Dispose(false);&lt;br /&gt;
            /// }&lt;br /&gt;
            /// &lt;br /&gt;
            /// // The internal Dispose, as per Wagner.&lt;br /&gt;
            /// protected virtual void Dispose(bool disposing)&lt;br /&gt;
            /// {&lt;br /&gt;
            /// // Ask the MustDispose whether it has been disposed yet.&lt;br /&gt;
            /// if (!mDispose.Disposed)&lt;br /&gt;
            /// {&lt;br /&gt;
            /// if (disposing)&lt;br /&gt;
            /// {&lt;br /&gt;
            /// DisposeBrush();&lt;br /&gt;
            /// }&lt;br /&gt;
            /// }&lt;br /&gt;
            /// &lt;br /&gt;
            /// // Dispose the MustDispose. VERY IMPORTANT! Otherwise, the&lt;br /&gt;
            /// // MustDispose will falsely report resource leaks.&lt;br /&gt;
            /// mDispose.Dispose();&lt;br /&gt;
            /// }&lt;br /&gt;
            /// &lt;br /&gt;
            /// // The standard Dispose implementation, as per Wagner.&lt;br /&gt;
            /// public void Dispose()&lt;br /&gt;
            /// {&lt;br /&gt;
            /// Dispose(true);&lt;br /&gt;
            /// GC.SuppressFinalize(this);&lt;br /&gt;
            /// }&lt;br /&gt;
            /// }&lt;br /&gt;
            /// &amp;lt;/example&amp;gt;&lt;br /&gt;
            public class MustDispose : IDisposable&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;font face="Courier New"&gt;#region Fields.&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// The type name of the object which was allocated but not disposed.&lt;br /&gt;
            /// Defaults to this type name.&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            private string mOwnerTypeName = "MustDispose";&lt;br /&gt;
            &lt;br /&gt;
            #endregion&lt;br /&gt;
            &lt;br /&gt;
            #region Properties with fields.&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// Have we disposed this MustDispose yet?&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            private bool mDisposed = false;&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// Have we disposed this MustDispose yet? Read only.&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            public bool Disposed&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;font face="Courier New"&gt;get { return mDisposed; }&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// Are we supposed to throw an exception when an object is lost?&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            private bool mThrow = true;&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// Are we supposed to throw an exception when an object is lost?&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            public bool Throw&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;font face="Courier New"&gt;get { return mThrow; }&lt;br /&gt;
            set { mThrow = value; }&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// Are we supposed to log an event when an object is lost?&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            private bool mLog = false;&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// Are we supposed to log an event when an object is lost?&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            public bool Log&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;font face="Courier New"&gt;get { return mLog; }&lt;br /&gt;
            set { mLog = value; }&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// An optional reason why Dispose is required.&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            private string mReason = "";&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// An optional reason why Dispose is required.&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            public string Reason&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;font face="Courier New"&gt;get { return mReason; }&lt;br /&gt;
            set { mReason = value; }&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;br /&gt;
            #endregion&lt;br /&gt;
            &lt;br /&gt;
            #region Construction and initialization.&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// Simple constructor. Sets the type name.&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            public MustDispose()&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;font face="Courier New"&gt;mOwnerTypeName = GetUndisposedTypeName();&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// Another constructor. Sets the control flags.&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            /// &amp;lt;param name="throwIfLost"&amp;gt;True if we should throw an exception&lt;br /&gt;
            /// for a lost object.&amp;lt;/param&amp;gt;&lt;br /&gt;
            /// &amp;lt;param name="logIfLost"&amp;gt;True if we should log an event for a&lt;br /&gt;
            /// lost object.&amp;lt;/param&amp;gt;&lt;br /&gt;
            public MustDispose(bool throwIfLost, bool logIfLost)&lt;br /&gt;
            &lt;/font&gt;&lt;font face="Courier New"&gt;: this()&lt;br /&gt;
            &lt;/font&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;{&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;mThrow = throwIfLost;&lt;br /&gt;
            mLog = logIfLost;&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// Most detailed constructor. Sets the control flags, and also a reason why&lt;br /&gt;
            /// disposing would be a good idea.&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            /// &amp;lt;param name="throwIfLost"&amp;gt;True if we should throw an exception for a lost object.&amp;lt;/param&amp;gt;&lt;br /&gt;
            /// &amp;lt;param name="logIfLost"&amp;gt;True if we should log an event for a lost object.&amp;lt;/param&amp;gt;&lt;br /&gt;
            /// &amp;lt;param name="reason"&amp;gt;What will go wrong if we don't dispose of the owner obect?&amp;lt;/param&amp;gt;&lt;br /&gt;
            public MustDispose(bool throwIfLost, bool logIfLost, string reason)&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;: this(throwIfLost, logIfLost)&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;{&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;mReason = reason;&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;br /&gt;
            #endregion&lt;br /&gt;
            &lt;br /&gt;
            #region Destruction and clean-up.&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// Finalizer.&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            ~MustDispose()&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;// Call the inner Dispose, as per Wagner.&lt;br /&gt;
            Dispose(false);&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// The internal Dispose, as described in Wagner's Effective C#.&lt;br /&gt;
            /// The purpose of the internal Dispose is to have a Dispose with chaining up an&lt;br /&gt;
            /// inheritance hierarchy, via virtual and override. This class is a root class,&lt;br /&gt;
            /// so does not need to chain up. At this time, there are no derived classes;&lt;br /&gt;
            /// but we're allowing for the possibility.&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            /// &amp;lt;param name="disposing"&amp;gt;&lt;br /&gt;
            /// True if this was called as part of an IDisposable.Dispose call; false if this&lt;br /&gt;
            /// was called as part of a finalizer.&lt;br /&gt;
            /// &amp;lt;/param&amp;gt;&lt;br /&gt;
            protected virtual void Dispose(bool disposing)&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;// Multiple Dispose calls must be nondestructive.&lt;br /&gt;
            if ( !mDisposed)&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;// We're disposed now. We need to set this flag RIGHT NOW. Otherwise, if we get&lt;br /&gt;
            // some sort of exception below, we'll fail the Dispose Pattern rule that&lt;br /&gt;
            // multiple Dispose calls must be non-destructive. That's actually not very&lt;br /&gt;
            // likely to be a problem (because any exceptions are only likely to occur&lt;br /&gt;
            // during finalization and Dispose calls after that are highly unlikely); but&lt;br /&gt;
            // better safe than sorry.&lt;br /&gt;
            mDisposed = true;&lt;br /&gt;
            &lt;br /&gt;
            // If we're called as part of a finalizer and we haven't been disposed&lt;br /&gt;
            // yet, that's a problem. The owner object expected to be disposed, dang it!&lt;br /&gt;
            if (!disposing)&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;// First, assert that we're disposing. Then possibly take harsher measures.&lt;br /&gt;
            System.Diagnostics.Debug.Assert(disposing, GetNotDisposedMessage());&lt;br /&gt;
            // Throw an exception, if expected.&lt;br /&gt;
            if (Throw)&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;ThrowNotDisposed();&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;br /&gt;
            // Log an event, if expected.&lt;br /&gt;
            if (Log)&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;LogNotDisposed();&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;br /&gt;
            #endregion&lt;br /&gt;
            &lt;br /&gt;
            #region IDisposable Members&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// The external dispose.&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            public void Dispose()&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;// Call the internal Dispose, as per Wagner.&lt;br /&gt;
            Dispose(true);&lt;br /&gt;
            &lt;br /&gt;
            // Suppress finalization. Not needed for final clean-up now.&lt;br /&gt;
            GC.SuppressFinalize(this);&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;br /&gt;
            #endregion&lt;br /&gt;
            &lt;br /&gt;
            #region Public worker methods.&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// Test to ensure this has not been disposed yet. Throw the&lt;br /&gt;
            /// appropriate exception if it has.&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            public void Test()&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;if (mDisposed)&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;ThrowDisposed();&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;br /&gt;
            #endregion&lt;br /&gt;
            &lt;br /&gt;
            #region Private worker methods.&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// Get the message to use when warning about a failure to dispose.&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            /// &amp;lt;returns&amp;gt;The message.&amp;lt;/returns&amp;gt;&lt;br /&gt;
            private string GetNotDisposedMessage()&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;string result = "Object of type " + mOwnerTypeName + " was not disposed. Possible resource leak!";&lt;br /&gt;
            if (Reason != "")&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;result += Environment.NewLine + Reason;&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            return result;&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// Get the message to use when warning about using a disposed object.&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            /// &amp;lt;returns&amp;gt;The message.&amp;lt;/returns&amp;gt;&lt;br /&gt;
            private string GetDisposedMessage()&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;return "Object of type " + mOwnerTypeName + " was used after being disposed. Possible corrupt resources!";&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// Get the type name of the object which was not disposed.&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            /// &amp;lt;returns&amp;gt;The type name.&amp;lt;/returns&amp;gt;&lt;br /&gt;
            private string GetUndisposedTypeName()&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;try&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;// We're going to use System.Diagnostics and System.Reflection&lt;br /&gt;
            // to find the owner object. Start by getting a stack trace.&lt;br /&gt;
            StackTrace st = new StackTrace();&lt;br /&gt;
            &lt;br /&gt;
            // Walk the stack, looking for a type other than MustDispose.&lt;br /&gt;
            // That will be the owner type.&lt;br /&gt;
            Type tThis = this.GetType();&lt;br /&gt;
            for (int i = 0; i &amp;lt; st.FrameCount; i++)&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;// Get the stack frame and the method.&lt;br /&gt;
            StackFrame sf = st.GetFrame(i);&lt;br /&gt;
            MethodBase m = sf.GetMethod();&lt;br /&gt;
            &lt;br /&gt;
            // Compare to MustDispose.&lt;br /&gt;
            if (m.DeclaringType != tThis)&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;return m.DeclaringType.Name;&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            catch&lt;br /&gt;
            {&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            // Never found an owner.&lt;br /&gt;
            return this.GetType().Name;&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// Throw a not-disposed exception, with explanation.&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            private void ThrowNotDisposed()&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;throw new Exception(GetNotDisposedMessage());&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// Log a not-disposed exception, with explanation.&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            private void LogNotDisposed()&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;string appName = System.IO.Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName);&lt;br /&gt;
            EventLog.WriteEntry(appName, GetDisposedMessage());&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;br /&gt;
            /// &amp;lt;summary&amp;gt;&lt;br /&gt;
            /// Throw a disposed exception, with explanation.&lt;br /&gt;
            /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
            private void ThrowDisposed()&lt;br /&gt;
            {&lt;br /&gt;
            &lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;throw new ObjectDisposedException(mOwnerTypeName, GetDisposedMessage());&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;br /&gt;
            #endregion&lt;br /&gt;
            &lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;/font&gt;
            &lt;/blockquote&gt;&lt;br /&gt;
            &lt;font face="Courier New"&gt;}&lt;br /&gt;
            &lt;/font&gt;&lt;/td&gt;
            &lt;font face="Courier New"&gt;&lt;/font&gt;
        &lt;/tr&gt;
        &lt;font face="Courier New"&gt;&lt;/font&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
Whew! There's a lot of code there, especially when you comment it thoroughly. So as promised, I'll give you some dissection.&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
&lt;br /&gt;
But before that, let's get to the good news: because MustDispose is so laboriously crafted, it's really easy to use in any class you design to be disposed. Stealing from the example code above, let's look at a class that must be disposed:&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;font face="Courier New"&gt;public class DisposableClass : IDisposable&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;// The single MustDispose.&lt;br /&gt;
private MustDispose mDispose = new MustDispose( true , true , "This object holds a brush, which must be released back to Windows when no longer needed." );&lt;br /&gt;
&lt;br /&gt;
// The brush that we must release when we're done.&lt;br /&gt;
protected Brush mBrush = null;&lt;br /&gt;
&lt;br /&gt;
// The color.&lt;br /&gt;
private Color mColor = Color.White;&lt;br /&gt;
&lt;br /&gt;
// The color. We will always create a matching brush.&lt;br /&gt;
public Color Color&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;get&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;// Note how we use the Test method of the MustDispose&lt;br /&gt;
// to verify that we're not disposed yet. It will&lt;br /&gt;
// throw the appropriate exception if we ARE disposed.&lt;br /&gt;
mDispose.Test();&lt;br /&gt;
return mColor;&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
set&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;// Note how we use the Test method of the MustDispose&lt;br /&gt;
// to verify that we're not disposed yet. It will&lt;br /&gt;
// throw the appropriate exception if we ARE disposed.&lt;br /&gt;
mDispose.Test();&lt;br /&gt;
mColor = value;&lt;br /&gt;
DisposeBrush();&lt;br /&gt;
mBrush = new SolidBrush(mColor);&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;br /&gt;
// Clean up the brush.&lt;br /&gt;
private void DisposeBrush()&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;// Note that we DON'T need a call to mDispose.Test() here.&lt;br /&gt;
// Since this is a private method, we're going to assume that&lt;br /&gt;
// we'll only call it when appropriate.&lt;br /&gt;
&lt;br /&gt;
if (mBrush != null)&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;mBrush.Dispose();&lt;br /&gt;
mBrush = null;&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;br /&gt;
// The Finalizer. Clean up here, if nowhere else.&lt;br /&gt;
~DisposableClass()&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;// Call the internal Dispose, as per Wagner.&lt;br /&gt;
Dispose(false);&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;br /&gt;
// The internal Dispose, as per Wagner.&lt;br /&gt;
protected virtual void Dispose(bool disposing)&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;// Ask the MustDispose whether it has been disposed yet.&lt;br /&gt;
if (!mDispose.Disposed)&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;if (disposing)&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;DisposeBrush();&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;br /&gt;
// Dispose the MustDispose. VERY IMPORTANT! Otherwise, the&lt;br /&gt;
// MustDispose will falsely report resource leaks.&lt;br /&gt;
mDispose.Dispose();&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;br /&gt;
// The standard Dispose implementation, as per Wagner.&lt;br /&gt;
public void Dispose()&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;Dispose(true);&lt;br /&gt;
GC.SuppressFinalize(this);&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
A lot of what you see there is just a robust Dispose() implementation, as described in Bill Wagner's book; and much of the rest is an example of grabbing and managing a resource (a Brush, in this example). The only place where the MustDispose comes into play is these sections:&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;// The single MustDispose.&lt;br /&gt;
private MustDispose mDispose = new MustDispose( true , true , "This object holds a brush, which must be released back to Windows when no longer needed." );&lt;br /&gt;
&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
To use a MustDispose, start by creating it as part of initializing or constructing your class.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;// Note how we use the Test method of the MustDispose&lt;br /&gt;
// to verify that we're not disposed yet. It will&lt;br /&gt;
// throw the appropriate exception if we ARE disposed.&lt;br /&gt;
mDispose.Test();&lt;br /&gt;
&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
We put a call to &lt;strong&gt;mDispose.Test()&lt;/strong&gt; at the start of each method. If the MustDispose has been disposed (and hence this object has as well), an ObjectDisposedException will be thrown, as required by the Dispose Pattern.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;// The internal Dispose, as per Wagner.&lt;br /&gt;
protected virtual void Dispose(bool disposing)&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;// Ask the MustDispose whether it has been disposed yet.&lt;br /&gt;
if (!mDispose.Disposed)&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;if (disposing)&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;DisposeBrush();&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;br /&gt;
// Dispose the MustDispose. VERY IMPORTANT! Otherwise, the&lt;br /&gt;
// MustDispose will falsely report resource leaks.&lt;br /&gt;
mDispose.Dispose();&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Note how, rather than maintain a separate boolean flag in the owner object, we simply ask the MustDispose to determine whether we have been disposed yet. Note also that the last thing our Dispose must do is dispose the MusDispose.&lt;br /&gt;
&lt;br /&gt;
So really, using a MustDispose is quite easy:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;br /&gt;
    &lt;li&gt;Create it as part of initializing your disposable class.&lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;Test it whenever you want to ensure that your disposable class has not yet been disposed.&lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;Use it as a boolean flag for whether your disposable class has been disposed yet or not.&lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;Dispose of it when you dispose of your disposable class.&lt;br /&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;br /&gt;
When you use MustDispose in these ways, it will automatically detect when you try to use an already-disposed object; and just as important, it will scream like a banshee when a disposable object is finalized instead of disposed. Most likely, that will all happen as the app is shutting down. If your client developers have been particularly sloppy, they (or your testers, or your customers) will probably get a slew of messages at app shutdown. They may also occur while running the app, but that's up to the .NET garbage collector: it finalizes objects when it decides to, and you have little say in the matter. (Again, see Bill Wagner's book.)&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
&lt;br /&gt;
So the tricky part, then, is in MustDispose. Let's dissect that, or at least the high points:&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;
/// Simple constructor. Sets the type name.&lt;br /&gt;
/// &amp;lt;/summary&amp;gt;&lt;br /&gt;
public MustDispose()&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;mOwnerTypeName = GetUndisposedTypeName();&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
The simple constructor reads the owner type name, as described below. The other constructors add functionality to the simple constructor.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;
/// The internal Dispose, as described in Wagner's Effective C#.&lt;br /&gt;
/// The purpose of the internal Dispose is to have a Dispose with chaining up an&lt;br /&gt;
/// inheritance hierarchy, via virtual and override. This class is a root class,&lt;br /&gt;
/// so does not need to chain up. At this time, there are no derived classes;&lt;br /&gt;
/// but we're allowing for the possibility.&lt;br /&gt;
/// &amp;lt;/summary&amp;gt;&lt;br /&gt;
/// &amp;lt;param name="disposing"&amp;gt;&lt;br /&gt;
/// True if this was called as part of an IDisposable.Dispose call; false if this&lt;br /&gt;
/// was called as part of a finalizer.&lt;br /&gt;
/// &amp;lt;/param&amp;gt;&lt;br /&gt;
protected virtual void Dispose(bool disposing)&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;// Multiple Dispose calls must be nondestructive.&lt;br /&gt;
if ( !mDisposed)&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;// We're disposed now. We need to set this flag RIGHT NOW. Otherwise, if we get&lt;br /&gt;
// some sort of exception below, we'll fail the Dispose Pattern rule that&lt;br /&gt;
// multiple Dispose calls must be non-destructive. That's actually not very&lt;br /&gt;
// likely to be a problem (because any exceptions are only likely to occur&lt;br /&gt;
// during finalization and Dispose calls after that are highly unlikely); but&lt;br /&gt;
// better safe than sorry.&lt;br /&gt;
mDisposed = true;&lt;br /&gt;
&lt;br /&gt;
// If we're called as part of a finalizer and we haven't been disposed&lt;br /&gt;
// yet, that's a problem. The owner object expected to be disposed, dang it!&lt;br /&gt;
if (!disposing)&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;// First, assert that we're disposing. Then possibly take harsher measures.&lt;br /&gt;
System.Diagnostics.Debug.Assert(disposing, GetNotDisposedMessage());&lt;br /&gt;
// Throw an exception, if expected.&lt;br /&gt;
if (Throw)&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;ThrowNotDisposed();&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;br /&gt;
// Log an event, if expected.&lt;br /&gt;
if (Log)&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;LogNotDisposed();&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
The internal Dispose really isn't all that complicated. It says simply: "If we're being finalized, assert that that's a problem. Also log and throw an exception, if so instructed."&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;
/// Get the type name of the object which was not disposed.&lt;br /&gt;
/// &amp;lt;/summary&amp;gt;&lt;br /&gt;
/// &amp;lt;returns&amp;gt;The type name.&amp;lt;/returns&amp;gt;&lt;br /&gt;
private string GetUndisposedTypeName()&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;try&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;// We're going to use System.Diagnostics and System.Reflection&lt;br /&gt;
// to find the owner object. Start by getting a stack trace.&lt;br /&gt;
StackTrace st = new StackTrace();&lt;br /&gt;
&lt;br /&gt;
// Walk the stack, looking for a type other than MustDispose.&lt;br /&gt;
// That will be the owner type.&lt;br /&gt;
Type tThis = this.GetType();&lt;br /&gt;
for (int i = 0; i &amp;lt; st.FrameCount; i++)&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;// Get the stack frame and the method.&lt;br /&gt;
StackFrame sf = st.GetFrame(i);&lt;br /&gt;
MethodBase m = sf.GetMethod();&lt;br /&gt;
&lt;br /&gt;
// Compare to MustDispose.&lt;br /&gt;
if (m.DeclaringType != tThis)&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;return m.DeclaringType.Name;&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
catch&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Never found an owner.&lt;br /&gt;
return this.GetType().Name;&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
This function is the key. I wanted MustDispose to find the owner name by itself, without having to be passed it as a parameter. Why? Two reasons:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
    &lt;li&gt;The class name might change during refactoring (or less structured maintenance). I didn't want the connection between the real name and the reported name to be "brittle".&lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;Sure as shootin', somebody's going to be too lazy to type the line of code that creates a MustDispose, and will just copy-and-paste it from another class. (Me!) And when they do, if there's a name parameter required, sure as shootin' they're gonna forget to change it. (Me again!) And then the whole purpose of MustDispose will be weakened: it will report that you failed to dispose, but it will report the wrong thing was undisposed.&lt;br /&gt;
    &lt;/li&gt;
&lt;/ul&gt;
So instead, I used System.Diagnostics to get a stack trace, and then walked it backwards using System.Reflection to compare types until I found a type other than MustDispose. That is, naturally, the owner type.&lt;br /&gt;
&lt;br /&gt;
The only downside to this approach is security. I'm no code access security expert; but I have to believe there are times when the System.Diagnostics or System.Reflection operations that I use are restricted. More research is called for there.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;
/// Log a not-disposed exception, with explanation.&lt;br /&gt;
/// &amp;lt;/summary&amp;gt;&lt;br /&gt;
private void LogNotDisposed()&lt;br /&gt;
{&lt;br /&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;string appName = System.IO.Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName);&lt;br /&gt;
EventLog.WriteEntry(appName, GetDisposedMessage());&lt;br /&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
For a very simplistic way of identifying the app in the Event Log, I used Process.GetCurrentProcess().MainModule.FileName. That may also present some security problems. Again, more research is needed.&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
&lt;br /&gt;
That's the code: how to use MustDispose, and how it works. But there's one missing piece of the solution here: the MustDispose process.&lt;br /&gt;
&lt;br /&gt;
What you're going to have to decide in your code is when to use MustDispose, how "loud" to make the messages, and what do you do about them? Do you turn them up really loud, and then have testers refuse to approve a build that has MustDispose errors? Do you make them really quiet and ship the code anyway? I can't make those calls for you. I've given you the tools, but now you have to decide how to use them.&lt;br /&gt;
&lt;br /&gt;
****************************************************************&lt;br /&gt;
&lt;br /&gt;
So that's it. I do agree with Richard that failure to dispose is a problem; I disagree that it's a problem peculiar to the &lt;strong&gt;using&lt;/strong&gt; statement. It's a problem with resource management and disposal in general. And nothing can make disposal automatic, it seems, no matter how hard we try. But with the proper use of MustDispose, it's at least easier to detect and diagnose when you have disposal failures.&lt;br /&gt;
&lt;br /&gt;
Remember what I said?&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;I disagree with him; but it will take time and sleep before I can fully explain why.&lt;br /&gt;
&lt;/blockquote&gt;I wasn't kidding!&lt;br /&gt;
&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=127071"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=127071" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/UlteriorMotiveLounge/aggbug/127071.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Martin L. Shoemaker</dc:creator>
            <guid>http://geekswithblogs.net/UlteriorMotiveLounge/archive/2008/11/15/richard-hale-shaw-says-put-up-or-shut-up.aspx</guid>
            <pubDate>Sat, 15 Nov 2008 22:00:26 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/UlteriorMotiveLounge/comments/127071.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/UlteriorMotiveLounge/archive/2008/11/15/richard-hale-shaw-says-put-up-or-shut-up.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/UlteriorMotiveLounge/comments/commentRss/127071.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>