<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" 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:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Chris Rauber</title>
    <link>http://www.chrisrauber.com/blog/</link>
    <description>this.Blog.Find(entry =&gt; entry.IsHelpful);</description>
    <language>en-us</language>
    <copyright>Chris Rauber</copyright>
    <lastBuildDate>Tue, 21 Oct 2008 13:00:12 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.0.7226.0</generator>
    <managingEditor>chris.rauber@gmail.com</managingEditor>
    <webMaster>chris.rauber@gmail.com</webMaster>
    <item>
      <trackback:ping>http://www.chrisrauber.com/blog/Trackback.aspx?guid=487e5abb-52ab-43bf-abcf-5badd63f41b4</trackback:ping>
      <pingback:server>http://www.chrisrauber.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.chrisrauber.com/blog/PermaLink,guid,487e5abb-52ab-43bf-abcf-5badd63f41b4.aspx</pingback:target>
      <dc:creator>Chris Rauber</dc:creator>
      <wfw:comment>http://www.chrisrauber.com/blog/CommentView,guid,487e5abb-52ab-43bf-abcf-5badd63f41b4.aspx</wfw:comment>
      <wfw:commentRss>http://www.chrisrauber.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=487e5abb-52ab-43bf-abcf-5badd63f41b4</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.thinktecture.com/" target="_blank">Thinktecture</a> has <a href="http://blogs.thinktecture.com/cweyer/archive/2008/10/19/415200.aspx" target="_blank">announced</a> that
their popular <a href="http://www.thinktecture.com/resourcearchive/tools-and-software/wscf" target="_blank">Web
Service Contract First tool (WSCF)</a> has been made available as an <a href="http://www.codeplex.com/WSCFclassic" target="_blank">open
source project</a> hosted on <a href="http://www.codeplex.com/" target="_blank">CodePlex</a>.
</p>
        <p>
I love using WSCF to build web service proxy interfaces for traditional asmx web services. 
It is a fantastic tool that greatly improves upon the traditional “Add a Web Reference”
functionality in Visual Studio.  The one thing I was always frustrated about
it was the (lack of) speed of its development, and the timeliness of keeping up with
.NET releases.  Hopefully, the open source community will rise to the challenge
and improve upon an already solid product.
</p>
        <img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=487e5abb-52ab-43bf-abcf-5badd63f41b4" />
      </body>
      <title>WSCF Moved to Open Source on CodePlex</title>
      <guid isPermaLink="false">http://www.chrisrauber.com/blog/PermaLink,guid,487e5abb-52ab-43bf-abcf-5badd63f41b4.aspx</guid>
      <link>http://www.chrisrauber.com/blog/2008/10/21/WSCFMovedToOpenSourceOnCodePlex.aspx</link>
      <pubDate>Tue, 21 Oct 2008 13:00:12 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://www.thinktecture.com/" target="_blank"&gt;Thinktecture&lt;/a&gt; has &lt;a href="http://blogs.thinktecture.com/cweyer/archive/2008/10/19/415200.aspx" target="_blank"&gt;announced&lt;/a&gt; that
their popular &lt;a href="http://www.thinktecture.com/resourcearchive/tools-and-software/wscf" target="_blank"&gt;Web
Service Contract First tool (WSCF)&lt;/a&gt; has been made available as an &lt;a href="http://www.codeplex.com/WSCFclassic" target="_blank"&gt;open
source project&lt;/a&gt; hosted on &lt;a href="http://www.codeplex.com/" target="_blank"&gt;CodePlex&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
I love using WSCF to build web service proxy interfaces for traditional asmx web services.&amp;nbsp;
It is a fantastic tool that greatly improves upon the traditional “Add a Web Reference”
functionality in Visual Studio.&amp;nbsp; The one thing I was always frustrated about
it was the (lack of) speed of its development, and the timeliness of keeping up with
.NET releases.&amp;nbsp; Hopefully, the open source community will rise to the challenge
and improve upon an already solid product.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=487e5abb-52ab-43bf-abcf-5badd63f41b4" /&gt;</description>
      <comments>http://www.chrisrauber.com/blog/CommentView,guid,487e5abb-52ab-43bf-abcf-5badd63f41b4.aspx</comments>
      <category>.Net</category>
      <category>Open Source</category>
      <category>Visual Studio</category>
      <category>Web Services</category>
    </item>
    <item>
      <trackback:ping>http://www.chrisrauber.com/blog/Trackback.aspx?guid=ae2b5dec-f79e-4571-8b99-a3f6e8912dc0</trackback:ping>
      <pingback:server>http://www.chrisrauber.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.chrisrauber.com/blog/PermaLink,guid,ae2b5dec-f79e-4571-8b99-a3f6e8912dc0.aspx</pingback:target>
      <dc:creator>Chris Rauber</dc:creator>
      <wfw:comment>http://www.chrisrauber.com/blog/CommentView,guid,ae2b5dec-f79e-4571-8b99-a3f6e8912dc0.aspx</wfw:comment>
      <wfw:commentRss>http://www.chrisrauber.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=ae2b5dec-f79e-4571-8b99-a3f6e8912dc0</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Looks like a busy end of the month for me.  I am going to try to attend the following
events in the next two weeks:
</p>
        <h5>
Atlanta Geek Dinner
</h5>
        <p>
          <a href="http://wildermuth.com/">Shawn Wildermuth</a> is hosting another <a href="http://www.geekdinners.com/DinnerInstance.aspx?id=13">Geek
Dinner</a> on the north side of town, at Pappadeaux’s in Alpharetta on October 23rd. 
I’ve missed the last few, so I’m really looking forward to getting back in the mix
on these.  I love Pappadeaux’s, but hate the fact it’s in Alpha-tucky. 
Oh well.
</p>
        <p>
          <a href="http://www.pappadeaux.com/">
            <strong>Pappadeaux Seafood Kitchen</strong>
          </a>
          <br />
10795 Davis Dr.<br />
Alpharetta,GA 30004<br />
770-992-5566
</p>
        <h5> 
</h5>
        <h5>Agile Atlanta
</h5>
        <p>
The <a href="http://www.agileatlanta.org/">Agile Atlanta User Group</a> is deviating
from their usual scheduled meeting of every 2nd Tuesday of the month for a special
event on Monday, October 27th.  <a href="http://jeffsutherland.com/">Jeff Sutherland</a>,
the co-creator of <a href="http://en.wikipedia.org/wiki/Scrum_%28management%29">Scrum</a> and
one of the authors of the <a href="http://agilemanifesto.org/">Agile Manifesto</a> is
presenting at Turner’s Techwood Campus location.  The topic is titled, <strong>“Hyperproductive
Distributed Scrum Teams”</strong>.  This is an amazing opportunity to hear one
of the true leaders in the Agile community speak.  Turner has very tight security,
so they are asking anybody who wishes to attend <a href="http://www.evite.com/pages/invite/viewInvite.jsp?event=SYHFSSKMCQCMQYVFBVWV&amp;inviteId=VOTBUVSVLTYUNAHMVGUD&amp;showPreview=false&amp;x=278748826">sign
up</a> beforehand.  You will need to sign up and present a photo ID for admittance
into the building.
</p>
        <p>
          <strong>Techwood Campus at Turner</strong>
          <br />
(1015 Assembly Room)<br />
1050 Techwood Drive N.W.<br />
Atlanta, GA 30318
</p>
        <h5> 
</h5>
        <h5>Atlanta ALT.Net 
</h5>
        <p>
The <a href="http://atlalt.net/screwturn/default.aspx?AspxAutoDetectCookieSupport=1">Atlanta
ALT.Net</a> group is holding another <a href="http://dotnet.meetup.com/134/calendar/8928424/">meetup</a> on
Wednesday, October 29th at <a href="http://www.thinkingmantavern.com/">Thinking Man
Tavern</a> in Decatur.  The topic of this meeting is Continuous Integration. 
Josh Gough has done a great job organizing these meetings, and I look forward to another
interesting and lively discussion.
</p>
        <p>
          <a href="http://www.thinkingmantavern.com/">
            <strong>Thinking Man Tavern</strong>
          </a>
          <br />
537 W Howard Ave 
<br />
Decatur, GA 30030 
<br /></p>
        <p>
          <br />
        </p>
        <img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=ae2b5dec-f79e-4571-8b99-a3f6e8912dc0" />
      </body>
      <title>Upcoming Events</title>
      <guid isPermaLink="false">http://www.chrisrauber.com/blog/PermaLink,guid,ae2b5dec-f79e-4571-8b99-a3f6e8912dc0.aspx</guid>
      <link>http://www.chrisrauber.com/blog/2008/10/18/UpcomingEvents.aspx</link>
      <pubDate>Sat, 18 Oct 2008 23:30:00 GMT</pubDate>
      <description>&lt;p&gt;
Looks like a busy end of the month for me.&amp;nbsp; I am going to try to attend the following
events in the next two weeks:
&lt;/p&gt;
&lt;h5&gt;
Atlanta Geek Dinner
&lt;/h5&gt;
&lt;p&gt;
&lt;a href="http://wildermuth.com/"&gt;Shawn Wildermuth&lt;/a&gt; is hosting another &lt;a href="http://www.geekdinners.com/DinnerInstance.aspx?id=13"&gt;Geek
Dinner&lt;/a&gt; on the north side of town, at Pappadeaux’s in Alpharetta on October 23rd.&amp;nbsp;
I’ve missed the last few, so I’m really looking forward to getting back in the mix
on these.&amp;nbsp; I love Pappadeaux’s, but hate the fact it’s in Alpha-tucky.&amp;nbsp;
Oh well.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.pappadeaux.com/"&gt;&lt;strong&gt;Pappadeaux Seafood Kitchen&lt;/strong&gt;&lt;/a&gt;
&lt;br&gt;
10795 Davis Dr.&lt;br&gt;
Alpharetta,GA 30004&lt;br&gt;
770-992-5566
&lt;/p&gt;
&lt;h5&gt;&amp;nbsp;
&lt;/h5&gt;
&lt;h5&gt;Agile Atlanta
&lt;/h5&gt;
&lt;p&gt;
The &lt;a href="http://www.agileatlanta.org/"&gt;Agile Atlanta User Group&lt;/a&gt; is deviating
from their usual scheduled meeting of every 2nd Tuesday of the month for a special
event on Monday, October 27th.&amp;nbsp; &lt;a href="http://jeffsutherland.com/"&gt;Jeff Sutherland&lt;/a&gt;,
the co-creator of &lt;a href="http://en.wikipedia.org/wiki/Scrum_%28management%29"&gt;Scrum&lt;/a&gt; and
one of the authors of the &lt;a href="http://agilemanifesto.org/"&gt;Agile Manifesto&lt;/a&gt; is
presenting at Turner’s Techwood Campus location.&amp;nbsp; The topic is titled, &lt;strong&gt;“Hyperproductive
Distributed Scrum Teams”&lt;/strong&gt;.&amp;nbsp; This is an amazing opportunity to hear one
of the true leaders in the Agile community speak.&amp;nbsp; Turner has very tight security,
so they are asking anybody who wishes to attend &lt;a href="http://www.evite.com/pages/invite/viewInvite.jsp?event=SYHFSSKMCQCMQYVFBVWV&amp;amp;inviteId=VOTBUVSVLTYUNAHMVGUD&amp;amp;showPreview=false&amp;amp;x=278748826"&gt;sign
up&lt;/a&gt; beforehand.&amp;nbsp; You will need to sign up and present a photo ID for admittance
into the building.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Techwood Campus at Turner&lt;/strong&gt; 
&lt;br&gt;
(1015 Assembly Room)&lt;br&gt;
1050 Techwood Drive N.W.&lt;br&gt;
Atlanta, GA 30318
&lt;/p&gt;
&lt;h5&gt;&amp;nbsp;
&lt;/h5&gt;
&lt;h5&gt;Atlanta ALT.Net 
&lt;/h5&gt;
&lt;p&gt;
The &lt;a href="http://atlalt.net/screwturn/default.aspx?AspxAutoDetectCookieSupport=1"&gt;Atlanta
ALT.Net&lt;/a&gt; group is holding another &lt;a href="http://dotnet.meetup.com/134/calendar/8928424/"&gt;meetup&lt;/a&gt; on
Wednesday, October 29th at &lt;a href="http://www.thinkingmantavern.com/"&gt;Thinking Man
Tavern&lt;/a&gt; in Decatur.&amp;nbsp; The topic of this meeting is Continuous Integration.&amp;nbsp;
Josh Gough has done a great job organizing these meetings, and I look forward to another
interesting and lively discussion.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.thinkingmantavern.com/"&gt;&lt;strong&gt;Thinking Man Tavern&lt;/strong&gt;&lt;/a&gt; 
&lt;br&gt;
537 W Howard Ave 
&lt;br&gt;
Decatur, GA 30030 
&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=ae2b5dec-f79e-4571-8b99-a3f6e8912dc0" /&gt;</description>
      <comments>http://www.chrisrauber.com/blog/CommentView,guid,ae2b5dec-f79e-4571-8b99-a3f6e8912dc0.aspx</comments>
      <category>Agile</category>
      <category>alt.net</category>
      <category>Programming</category>
      <category>User Groups</category>
    </item>
    <item>
      <trackback:ping>http://www.chrisrauber.com/blog/Trackback.aspx?guid=9b19e136-49fd-4a49-8589-e520dfefaa3b</trackback:ping>
      <pingback:server>http://www.chrisrauber.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.chrisrauber.com/blog/PermaLink,guid,9b19e136-49fd-4a49-8589-e520dfefaa3b.aspx</pingback:target>
      <dc:creator>Chris Rauber</dc:creator>
      <wfw:comment>http://www.chrisrauber.com/blog/CommentView,guid,9b19e136-49fd-4a49-8589-e520dfefaa3b.aspx</wfw:comment>
      <wfw:commentRss>http://www.chrisrauber.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=9b19e136-49fd-4a49-8589-e520dfefaa3b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
During our daily standup the other day, one of the developers was complaining about
the lack of commenting in a module that was written by a 3rd party consulting firm. 
This got many frustrated nods from the other developers in the group, which in turn
led to a discussion of comments overall in our code.  There seemed to be a general
consensus among the group that the commenting in our code needed to be improved overall.
</p>
        <p>
The reason I found it interesting (and by interesting I mean to me only) was the the
timing of it all.  
</p>
        <p>
I’ve been on a kick lately to read nothing but Agile books (instead of the usual books
on specific languages or technologies).  The one currently occupying my bedside
table is a book by <a href="http://blog.objectmentor.com/articles/category/uncle-bobs-blatherings">Robert
C. Martin</a> (aka “Uncle Bob”) called <a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1224294466&amp;sr=8-1"><u>Clean
Code : An Handbook of Agile Software Craftsmanship</u></a>.  
</p>
        <p>
Literally only a day or two before this particular stand-up meeting, I had read the
section on commenting in the book.  In fact, Uncle Bob’s views on the subject
were so strong that he dedicated an entire chapter to it.  He argues that comments
overall are a “necessary evil” and are only needed as a means “to compensate for our
failure to express ourself in code.”  He hopes someday that languages evolve
to <a href="http://en.wikipedia.org/wiki/Domain-specific_language">DSLs</a> that are
self-documenting.
</p>
        <p>
He reasons that comments are bad because Agile code changes over time.  Oftentimes,
the comments don’t get maintained along with the code.  So the more code gets
changed, the comments become further away from the current intent of that code. 
In fact, he boldly states that comments lie (though not necessarily intentionally),
and that inaccurate comments do more harm than no comments at all.  A bad comment
is worse than no comment (maybe Uncle Bob was a lawyer in a former life?).  
</p>
        <p>
Well, if that’s the case, why bother commenting at all?
</p>
        <p>
He does give some examples of <strong>useful comments</strong>:
</p>
        <ul>
          <li>
Legal comments, such as copyright headers, author statements, or ownership rights 
</li>
          <li>
Warning of consequences 
</li>
          <li>
TODO comments, which can be caught in IDEs as warnings</li>
        </ul>
        <p>
On the other hand, he provides numerous examples of <strong>bad comments</strong>:
</p>
        <ul>
          <li>
Documenting a “hack” 
</li>
          <li>
Comments that mirror the functionality and/or naming of the code piece it describes 
</li>
          <li>
Poorly written comments, which can be harder to read than the code itself 
</li>
          <li>
Journal comments that log each time the code is changed 
</li>
          <li>
Noisy comments that provide no value (e.g.<font face="Consolas"> // ignore</font> ) 
</li>
          <li>
Position markers (e.g.<font face="Consolas"> //////// Public Methods /////////////</font>) 
</li>
          <li>
Closing brace comments (e.g. <font face="Consolas">// end while</font>) 
</li>
          <li>
Commented out refactored code (a personal pet peeve of mine)</li>
        </ul>
        <p>
I don’t know if I agree with the extremist approach of removing all comments from
my code.  But I do agree that comments are often abused as a replacement for
good code.  The rule of thumb I came away from the book is: if you feel the need
to document a complex chunk of code with a comment, that is a sure-fire sign of a
code smell.  Step back and look at the code from an maintenance perspective. 
Is this code likely to change?  What are the odds the comments will change with
it?  Is the comment articulating my intent well?  Have I named my variables/methods/classes
intuitively?  Most importantly - can I refactor the code into a standalone method
that can be named expressively?
</p>
        <p>
Comments can be useful, but many times end up being the poor man’s excuse for lazy
coding.  Don’t be that guy (or gal).  Strive to make your code readable
without having to resort to comments.
</p>
        <img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=9b19e136-49fd-4a49-8589-e520dfefaa3b" />
      </body>
      <title>No Comment</title>
      <guid isPermaLink="false">http://www.chrisrauber.com/blog/PermaLink,guid,9b19e136-49fd-4a49-8589-e520dfefaa3b.aspx</guid>
      <link>http://www.chrisrauber.com/blog/2008/10/18/NoComment.aspx</link>
      <pubDate>Sat, 18 Oct 2008 01:54:34 GMT</pubDate>
      <description>&lt;p&gt;
During our daily standup the other day, one of the developers was complaining about
the lack of commenting in a module that was written by a 3rd party consulting firm.&amp;nbsp;
This got many frustrated nods from the other developers in the group, which in turn
led to a discussion of comments overall in our code.&amp;nbsp; There seemed to be a general
consensus among the group that the commenting in our code needed to be improved overall.
&lt;/p&gt;
&lt;p&gt;
The reason I found it interesting (and by interesting I mean to me only) was the the
timing of it all.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
I’ve been on a kick lately to read nothing but Agile books (instead of the usual books
on specific languages or technologies).&amp;nbsp; The one currently occupying my bedside
table is a book by &lt;a href="http://blog.objectmentor.com/articles/category/uncle-bobs-blatherings"&gt;Robert
C. Martin&lt;/a&gt; (aka “Uncle Bob”) called &lt;a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1224294466&amp;amp;sr=8-1"&gt;&lt;u&gt;Clean
Code : An Handbook of Agile Software Craftsmanship&lt;/u&gt;&lt;/a&gt;.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Literally only a day or two before this particular stand-up meeting, I had read the
section on commenting in the book.&amp;nbsp; In fact, Uncle Bob’s views on the subject
were so strong that he dedicated an entire chapter to it.&amp;nbsp; He argues that comments
overall are a “necessary evil” and are only needed as a means “to compensate for our
failure to express ourself in code.”&amp;nbsp; He hopes someday that languages evolve
to &lt;a href="http://en.wikipedia.org/wiki/Domain-specific_language"&gt;DSLs&lt;/a&gt; that are
self-documenting.
&lt;/p&gt;
&lt;p&gt;
He reasons that comments are bad because Agile code changes over time.&amp;nbsp; Oftentimes,
the comments don’t get maintained along with the code.&amp;nbsp; So the more code gets
changed, the comments become further away from the current intent of that code.&amp;nbsp;
In fact, he boldly states that comments lie (though not necessarily intentionally),
and that inaccurate comments do more harm than no comments at all.&amp;nbsp; A bad comment
is worse than no comment (maybe Uncle Bob was a lawyer in a former life?).&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Well, if that’s the case, why bother commenting at all?
&lt;/p&gt;
&lt;p&gt;
He does give some examples of &lt;strong&gt;useful comments&lt;/strong&gt;:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Legal comments, such as copyright headers, author statements, or ownership rights 
&lt;/li&gt;
&lt;li&gt;
Warning of consequences 
&lt;/li&gt;
&lt;li&gt;
TODO comments, which can be caught in IDEs as warnings&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
On the other hand, he provides numerous examples of &lt;strong&gt;bad comments&lt;/strong&gt;:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Documenting a “hack” 
&lt;/li&gt;
&lt;li&gt;
Comments that mirror the functionality and/or naming of the code piece it describes 
&lt;/li&gt;
&lt;li&gt;
Poorly written comments, which can be harder to read than the code itself 
&lt;/li&gt;
&lt;li&gt;
Journal comments that log each time the code is changed 
&lt;/li&gt;
&lt;li&gt;
Noisy comments that provide no value (e.g.&lt;font face="Consolas"&gt; // ignore&lt;/font&gt; ) 
&lt;/li&gt;
&lt;li&gt;
Position markers (e.g.&lt;font face="Consolas"&gt; //////// Public Methods /////////////&lt;/font&gt;) 
&lt;/li&gt;
&lt;li&gt;
Closing brace comments (e.g. &lt;font face="Consolas"&gt;// end while&lt;/font&gt;) 
&lt;/li&gt;
&lt;li&gt;
Commented out refactored code (a personal pet peeve of mine)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I don’t know if I agree with the extremist approach of removing all comments from
my code.&amp;nbsp; But I do agree that comments are often abused as a replacement for
good code.&amp;nbsp; The rule of thumb I came away from the book is: if you feel the need
to document a complex chunk of code with a comment, that is a sure-fire sign of a
code smell.&amp;nbsp; Step back and look at the code from an maintenance perspective.&amp;nbsp;
Is this code likely to change?&amp;nbsp; What are the odds the comments will change with
it?&amp;nbsp; Is the comment articulating my intent well?&amp;nbsp; Have I named my variables/methods/classes
intuitively?&amp;nbsp; Most importantly - can I refactor the code into a standalone method
that can be named expressively?
&lt;/p&gt;
&lt;p&gt;
Comments can be useful, but many times end up being the poor man’s excuse for lazy
coding.&amp;nbsp; Don’t be that guy (or gal).&amp;nbsp; Strive to make your code readable
without having to resort to comments.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=9b19e136-49fd-4a49-8589-e520dfefaa3b" /&gt;</description>
      <comments>http://www.chrisrauber.com/blog/CommentView,guid,9b19e136-49fd-4a49-8589-e520dfefaa3b.aspx</comments>
      <category>Agile</category>
      <category>Back To Basics</category>
      <category>Programming</category>
    </item>
    <item>
      <trackback:ping>http://www.chrisrauber.com/blog/Trackback.aspx?guid=2df3f88b-6b67-4aac-822c-9a1c1497a04f</trackback:ping>
      <pingback:server>http://www.chrisrauber.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.chrisrauber.com/blog/PermaLink,guid,2df3f88b-6b67-4aac-822c-9a1c1497a04f.aspx</pingback:target>
      <dc:creator>Chris Rauber</dc:creator>
      <wfw:comment>http://www.chrisrauber.com/blog/CommentView,guid,2df3f88b-6b67-4aac-822c-9a1c1497a04f.aspx</wfw:comment>
      <wfw:commentRss>http://www.chrisrauber.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=2df3f88b-6b67-4aac-822c-9a1c1497a04f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I heard on the latest <a target="_blank" href="http://twit.tv/ww">Windows Weekly</a> podcast
that Microsoft has posted a new update to their <a target="_blank" href="http://windowslivewire.spaces.live.com/">Live
application suite</a>.
</p>
        <p>
The <a target="_blank" href="http://download.live.com/">Windows Live Wave 3 release</a> includes
updates to two applications I use frequently - <a target="_blank" href="http://download.live.com/writer">Live
Writer</a> (which I’m using to write this blog post!) and <a target="_blank" href="http://download.live.com/messenger">Live
Messenger</a>.  The changes aren’t overwhelming, but do add some polish to the
UI and give it a little more of an “Aero” type feel.  
</p>
        <p>
 
</p>
        <p>
          <a href="http://www.chrisrauber.com/blog/content/binary/WindowsLiveWriter/NewLiveWriterandLiveMessengerreleased_8731/messenger_wave_3_4.jpg">
            <img style="border-right-width: 0px; margin: 0px 0px 0px 20px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="messenger_wave_3" border="0" alt="messenger_wave_3" src="http://www.chrisrauber.com/blog/content/binary/WindowsLiveWriter/NewLiveWriterandLiveMessengerreleased_8731/messenger_wave_3_thumb_1.jpg" width="410" height="500" />
          </a>
        </p>
        <img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=2df3f88b-6b67-4aac-822c-9a1c1497a04f" />
      </body>
      <title>New update to Windows Live applications released</title>
      <guid isPermaLink="false">http://www.chrisrauber.com/blog/PermaLink,guid,2df3f88b-6b67-4aac-822c-9a1c1497a04f.aspx</guid>
      <link>http://www.chrisrauber.com/blog/2008/09/25/NewUpdateToWindowsLiveApplicationsReleased.aspx</link>
      <pubDate>Thu, 25 Sep 2008 13:40:20 GMT</pubDate>
      <description>&lt;p&gt;
I heard on the latest &lt;a target="_blank" href="http://twit.tv/ww"&gt;Windows Weekly&lt;/a&gt; podcast
that Microsoft has posted a new update to their &lt;a target="_blank" href="http://windowslivewire.spaces.live.com/"&gt;Live
application suite&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
The &lt;a target="_blank" href="http://download.live.com/"&gt;Windows Live Wave 3 release&lt;/a&gt; includes
updates to two applications I use frequently - &lt;a target="_blank" href="http://download.live.com/writer"&gt;Live
Writer&lt;/a&gt; (which I’m using to write this blog post!) and &lt;a target="_blank" href="http://download.live.com/messenger"&gt;Live
Messenger&lt;/a&gt;.&amp;nbsp; The changes aren’t overwhelming, but do add some polish to the
UI and give it a little more of an “Aero” type feel.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.chrisrauber.com/blog/content/binary/WindowsLiveWriter/NewLiveWriterandLiveMessengerreleased_8731/messenger_wave_3_4.jpg"&gt;&lt;img style="border-right-width: 0px; margin: 0px 0px 0px 20px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="messenger_wave_3" border="0" alt="messenger_wave_3" src="http://www.chrisrauber.com/blog/content/binary/WindowsLiveWriter/NewLiveWriterandLiveMessengerreleased_8731/messenger_wave_3_thumb_1.jpg" width="410" height="500"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=2df3f88b-6b67-4aac-822c-9a1c1497a04f" /&gt;</description>
      <comments>http://www.chrisrauber.com/blog/CommentView,guid,2df3f88b-6b67-4aac-822c-9a1c1497a04f.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.chrisrauber.com/blog/Trackback.aspx?guid=aca76c1b-3472-4fbe-8b9a-3caa29815414</trackback:ping>
      <pingback:server>http://www.chrisrauber.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.chrisrauber.com/blog/PermaLink,guid,aca76c1b-3472-4fbe-8b9a-3caa29815414.aspx</pingback:target>
      <dc:creator>Chris Rauber</dc:creator>
      <wfw:comment>http://www.chrisrauber.com/blog/CommentView,guid,aca76c1b-3472-4fbe-8b9a-3caa29815414.aspx</wfw:comment>
      <wfw:commentRss>http://www.chrisrauber.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=aca76c1b-3472-4fbe-8b9a-3caa29815414</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've come across all kinds of architectures in my time.  Some have been good,
some bad (yet somehow the bad vastly outnumber the good).  Even on some of the
good architectures I've seen, a common problem I've found is the abuse of object inheritance.  
</p>
        <p>
It's tempting to create an inheritance hierarchy to quickly get all the functionality
provided by a common base class.  Through one little symbol or keyword, you can
easily extend your object to get all the functionality provided by some other class. 
However, be aware this kind of modeling comes with a price, and many times it's a
price more steep than you should be willing to pay.  
</p>
        <p>
Which is why a lot of people much smarter than me - Josh Bloch, Venkat Subramaniam,
Andy Hunt, Dave Thomas, Robert "Uncle Bob" Martin, and Steve McConnell - have all
argued that using composition instead of inheritance creates a much more Agile object
model.  There are many reasons why Agile developers feel this way.
</p>
        <h3>Conceptually
</h3>
        <h5>"Is-a" vs. "Has-a"
</h5>
        <p>
In inheritance modeling, class inheritance should only be used to represent true "subtype"
relationships.  Every subclass should be a subtype of the class it is extending. 
Object B should only extend Object A if a logical "is-a" relationship exists. 
In other words, you need to ask yourself, "Is every B really an A?"  If you cannot
truthfully answer yes to this question, there is no reason for B to extend A other
than simple convenience.  And convenience is not a good reason for creating an
inheritance hierarchy.  
</p>
        <p>
Steve McConnell explains further in his seminal book Code Complete, 
</p>
        <blockquote>
          <p>
"If the derived class isn't going to adhere completely to the same interface contract
defined by the base class, inheritance is not the right implementation technique."
</p>
        </blockquote>
        <p>
Rather, you are better served modeling a "has-a" relationship between the two classes,
where A is a private instance in the implementation details of B.  B may depend
on the services provided by A, but is not a logical subtype of it.  By "wrapping"
the reference to A, you will have a more conceptually accurate and flexible implementation.
</p>
        <h5>It's all about the context!
</h5>
        <p>
A consumer of an object should be able to intuitively decipher its purpose from its
public API.  When you force an inheritance hierarchy of two objects that don't
have an "is-a" relationship, you have created an subclass object that contains methods,
properties, fields, etc. from two different contexts.  By combining these contexts,
you have created a confusing API that causes the consumer of it to have to actively
track down the meaning behind methods exposed from the two contexts.
</p>
        <p>
For example, suppose I have an Account object that extends TransactionCoordinator. 
The two objects have two different contexts, and the design of their individual APIs
most likely reflect that fact.  As a consumer of the Account object, when I see
methods such as Start(), Commit(), Rollback() that have been inherited from the base
class representing a different context, I am confused.  Intuitively, an Account
is not a TransactionCoordinator, and I would have to know that inheritance relationship
even exists to understand why I am seeing these methods.  Normally, I wouldn't
expect to see them there.  What do these methods mean?  What do they do? 
If I'm lucky, I can look at the API documentation (if it exists) on the Account object
and it will detail each method and its functionality and implications when called
from the subclass.  More likely, I will have to open the Account object up, see
that it extends the TransactionCoordinator, and go there to research what each method
actually does.  And only then can I have the ability to decide if that behavior
is something I want to invoke on my subclass.
</p>
        <p>
Here’s the lesson - don't make consumers of your API work any harder than they have
to.
</p>
        <h5>Liskov's Substitution Principle
</h5>
        <p>
          <a target="_blank" href="http://en.wikipedia.org/wiki/Barbara_Liskov">Barbara Liskov</a> wrote
one of most ground-breaking papers on object-oriented programming in 1998.  In
this paper, Liskov proposed that you shouldn't inherit from a base class unless the
derived class truly "is-a" more specific version of the base class.  In what
became known as the <a target="_blank" href="http://en.wikipedia.org/wiki/Liskov_substitution_principle">"Liskov
Substitution Principle"</a>, Liskov argued that any derived class must be able to
be completely substituted for its base class interface without any knowledge of the
calling class.  In other words, subclasses must only change the <em>implementation</em> and
not the <em>meaning or intent</em> of the base class interface.  
</p>
        <p>
Say you have an abstract base Account object.  Callers that reference the base
class API should not have to know or care which whether a CheckingAccount or SavingsAccount
derived class actually provides the implementation.  To take the example further,
suppose there is a CalculateInterest() method declared on the Account object. 
In normal implementations it calculates the interest due to the consumer.  Suppose
you introduce a BankLoanAccount which changes the implementation to calculate the
interest for the bank.  This class violates the LSP since it changes the meaning
of the implementation of the CalculateInterest() method, so now the caller cannot
freely call the method on the base class reference.
</p>
        <h5>Single Responsibility Principle
</h5>
        <p>
I'm a firm believer in the <a target="_blank" href="http://en.wikipedia.org/wiki/Single_responsibility_principle">Single
Responsibility Principle</a>.  Classes should have one responsibility, and one
responsibility only.  Think of it as the old <a target="_blank" href="http://en.wikipedia.org/wiki/Assembly_line#Ford_Motor_Company_.281908-1913.29">Henry
Ford assembly line</a> - classes should do their one thing and do it well.  There
is no reason for them to know the inner details or the workings in the classes in
which it interacts.  This leads to smaller, more focused classes.  And small,
purposeful classes are A GOOD THING.  
</p>
        <p>
Single responsibility creates classes that are highly cohesive, while limiting coupling
to external dependencies.  High cohesion and low coupling is an admirable goal
in any software architecture.
</p>
        <h5>Planning for change
</h5>
        <p>
By limiting classes to one responsibility, you are also creating a class that has
only one reason to change.  As a developer who believes in Agile methodologies,
I know change is going to come.  Limiting the reasons for classes to change,
as well as the surface area in which that change will be felt, will go a long way
towards making those changes easier to implement.
</p>
        <h2>Technical
</h2>
        <h5>
          <strong>Introduces Dependencies</strong>
        </h5>
        <p>
Anytime you inherit from a class, you are explicitly creating a dependency on that
super class.  The code to the super class may change over time.  Each time
it does change, it can potentially directly or indirectly break some or all of its
subclasses, even though the code in subclasses may not have changed at all. 
Most likely, the subclasses had no idea the change even occurred at all.  And
unless you have planned for this contingency in your unit test (you <strong>are</strong> writing
unit tests, right???), you may not even find this breaking change until after the
code is deployed.  And if you are writing unit tests, that's just more (seemingly
avoidable) unit tests you need to write to handle these cases.
</p>
        <p>
This creates a lot more work for the API producer.  All subclasses now will have
to be designed (and tested) to evolve in conjunction with their super classes. 
That's more code and more unit tests you now have to write and maintain.
</p>
        <h5>Fragile classes
</h5>
        <p>
Due to rules we must live with when choosing a static, compiled language, we limit
ourselves in the structuring of our API.  Anytime we define a method signature
in any class, this signature causes a ripple effect up and down the inheritance hierarchy. 
That's both good and bad.  Each base class automatically inherits the new functionality,
but guess what - it may not want to do so.  Or worse yet, it can break existing
functionality in the subclass.
</p>
        <p>
For example, introducing or changing a method signature in the base class will flow
down to every class that derives from it.  What if that subclass already has
a method defined in that class with the same name?  This will cause either: a
compilation error if the method cannot be overridden; or worse yet unexpected behavior
at runtime if the method can be overridden as the subclass implementation is now unknowingly
invoked.  Or, what about if the subclass has the same method name but a different
signature?  You will be forced to change your API in one of the classes just
to get them to compile.  The same problems manifest itself as methods are introduced
in base classes, but at least you are a probably little more aware of the potentially
breaking changes.
</p>
        <p>
Think this is a far-fetched example?  I don't.  Imagine common method names
like Execute(), Activate(), Register(), or IsAvailable(), Open(), Load(), or Save(). 
All of these are all methods names that are prolific in our object models, and could
easily have much different signatures as well as potentially meaning very different
things in different contexts.
</p>
        <p>
What if the behavior introduced in a base class implementation is not desired in the
subclass?  Sorry, your S.O.L.  Good and bad, you get everything that comes
down from the base.
</p>
        <h5>Refactoring
</h5>
        <p>
Due to all the problems with carrying "API baggage", classes with deep hierarchies
are much harder to refactor.  Are you completely comfortable with the API provided
by your super class?  Because anytime you extend it, any flaws/issues/concerns
you have with it are propagated down to the subclasses.  Not only that, the flaws
now become further spread across your object model through the expanded surface area
of all of its own and now its subclasses consumers.  Composition is much more
flexible.  It has the advantage of masking, improving, or changing the API to
encapsulate the existing concerns.
</p>
        <p>
Not only that, but now you have tied yourself to this mis-matched inheritance hierarchy,
and it will be much harder to introduce a new base class if a new valid one ever presents
itself.
</p>
        <h3>Summary
</h3>
        <p>
Inheritances is one of the most powerful and most abused concepts in object-oriented
programming languages today.  True, inheritance is an easy and useful way to
provide quick code reusability across your object model.  But the drawbacks of
doing so far outweigh the short-term gains achieved.  Oftentimes the reusability
gained comes as the expense of code extensibility, maintainability, and testability. 
In the long run, ironically both producers and consumers of the API will have to do
more work to maintain the fragile inheritance hierarchy.  Favor composition over
inheritance to limit fragile inheritance hierarchies and create a much more flexible
and powerful API.
</p>
        <img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=aca76c1b-3472-4fbe-8b9a-3caa29815414" />
      </body>
      <title>Favor Composition Over Inheritance</title>
      <guid isPermaLink="false">http://www.chrisrauber.com/blog/PermaLink,guid,aca76c1b-3472-4fbe-8b9a-3caa29815414.aspx</guid>
      <link>http://www.chrisrauber.com/blog/2008/09/25/FavorCompositionOverInheritance.aspx</link>
      <pubDate>Thu, 25 Sep 2008 03:30:23 GMT</pubDate>
      <description>&lt;p&gt;
I've come across all kinds of architectures in my time.&amp;nbsp; Some have been good,
some bad (yet somehow the bad vastly outnumber the good).&amp;nbsp; Even on some of the
good architectures I've seen, a common problem I've found is the abuse of object inheritance.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
It's tempting to create an inheritance hierarchy to quickly get all the functionality
provided by a common base class.&amp;nbsp; Through one little symbol or keyword, you can
easily extend your object to get all the functionality provided by some other class.&amp;nbsp;
However, be aware this kind of modeling comes with a price, and many times it's a
price more steep than you should be willing to pay.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Which is why a lot of people much smarter than me - Josh Bloch, Venkat Subramaniam,
Andy Hunt, Dave Thomas, Robert "Uncle Bob" Martin, and Steve McConnell - have all
argued that using composition instead of inheritance creates a much more Agile object
model.&amp;nbsp; There are many reasons why Agile developers feel this way.
&lt;/p&gt;
&lt;h3&gt;Conceptually
&lt;/h3&gt;
&lt;h5&gt;"Is-a" vs. "Has-a"
&lt;/h5&gt;
&lt;p&gt;
In inheritance modeling, class inheritance should only be used to represent true "subtype"
relationships.&amp;nbsp; Every subclass should be a subtype of the class it is extending.&amp;nbsp;
Object B should only extend Object A if a logical "is-a" relationship exists.&amp;nbsp;
In other words, you need to ask yourself, "Is every B really an A?"&amp;nbsp; If you cannot
truthfully answer yes to this question, there is no reason for B to extend A other
than simple convenience.&amp;nbsp; And convenience is not a good reason for creating an
inheritance hierarchy.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Steve McConnell explains further in his seminal book Code Complete, 
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
"If the derived class isn't going to adhere completely to the same interface contract
defined by the base class, inheritance is not the right implementation technique."
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Rather, you are better served modeling a "has-a" relationship between the two classes,
where A is a private instance in the implementation details of B.&amp;nbsp; B may depend
on the services provided by A, but is not a logical subtype of it.&amp;nbsp; By "wrapping"
the reference to A, you will have a more conceptually accurate and flexible implementation.
&lt;/p&gt;
&lt;h5&gt;It's all about the context!
&lt;/h5&gt;
&lt;p&gt;
A consumer of an object should be able to intuitively decipher its purpose from its
public API.&amp;nbsp; When you force an inheritance hierarchy of two objects that don't
have an "is-a" relationship, you have created an subclass object that contains methods,
properties, fields, etc. from two different contexts.&amp;nbsp; By combining these contexts,
you have created a confusing API that causes the consumer of it to have to actively
track down the meaning behind methods exposed from the two contexts.
&lt;/p&gt;
&lt;p&gt;
For example, suppose I have an Account object that extends TransactionCoordinator.&amp;nbsp;
The two objects have two different contexts, and the design of their individual APIs
most likely reflect that fact.&amp;nbsp; As a consumer of the Account object, when I see
methods such as Start(), Commit(), Rollback() that have been inherited from the base
class representing a different context, I am confused.&amp;nbsp; Intuitively, an Account
is not a TransactionCoordinator, and I would have to know that inheritance relationship
even exists to understand why I am seeing these methods.&amp;nbsp; Normally, I wouldn't
expect to see them there.&amp;nbsp; What do these methods mean?&amp;nbsp; What do they do?&amp;nbsp;
If I'm lucky, I can look at the API documentation (if it exists) on the Account object
and it will detail each method and its functionality and implications when called
from the subclass.&amp;nbsp; More likely, I will have to open the Account object up, see
that it extends the TransactionCoordinator, and go there to research what each method
actually does.&amp;nbsp; And only then can I have the ability to decide if that behavior
is something I want to invoke on my subclass.
&lt;/p&gt;
&lt;p&gt;
Here’s the lesson - don't make consumers of your API work any harder than they have
to.
&lt;/p&gt;
&lt;h5&gt;Liskov's Substitution Principle
&lt;/h5&gt;
&lt;p&gt;
&lt;a target="_blank" href="http://en.wikipedia.org/wiki/Barbara_Liskov"&gt;Barbara Liskov&lt;/a&gt; wrote
one of most ground-breaking papers on object-oriented programming in 1998.&amp;nbsp; In
this paper, Liskov proposed that you shouldn't inherit from a base class unless the
derived class truly "is-a" more specific version of the base class.&amp;nbsp; In what
became known as the &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Liskov_substitution_principle"&gt;"Liskov
Substitution Principle"&lt;/a&gt;, Liskov argued that any derived class must be able to
be completely substituted for its base class interface without any knowledge of the
calling class.&amp;nbsp; In other words, subclasses must only change the &lt;em&gt;implementation&lt;/em&gt; and
not the &lt;em&gt;meaning or intent&lt;/em&gt; of the base class interface.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Say you have an abstract base Account object.&amp;nbsp; Callers that reference the base
class API should not have to know or care which whether a CheckingAccount or SavingsAccount
derived class actually provides the implementation.&amp;nbsp; To take the example further,
suppose there is a CalculateInterest() method declared on the Account object.&amp;nbsp;
In normal implementations it calculates the interest due to the consumer.&amp;nbsp; Suppose
you introduce a BankLoanAccount which changes the implementation to calculate the
interest for the bank.&amp;nbsp; This class violates the LSP since it changes the meaning
of the implementation of the CalculateInterest() method, so now the caller cannot
freely call the method on the base class reference.
&lt;/p&gt;
&lt;h5&gt;Single Responsibility Principle
&lt;/h5&gt;
&lt;p&gt;
I'm a firm believer in the &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Single_responsibility_principle"&gt;Single
Responsibility Principle&lt;/a&gt;.&amp;nbsp; Classes should have one responsibility, and one
responsibility only.&amp;nbsp; Think of it as the old &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Assembly_line#Ford_Motor_Company_.281908-1913.29"&gt;Henry
Ford assembly line&lt;/a&gt; - classes should do their one thing and do it well.&amp;nbsp; There
is no reason for them to know the inner details or the workings in the classes in
which it interacts.&amp;nbsp; This leads to smaller, more focused classes.&amp;nbsp; And small,
purposeful classes are A GOOD THING.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Single responsibility creates classes that are highly cohesive, while limiting coupling
to external dependencies.&amp;nbsp; High cohesion and low coupling is an admirable goal
in any software architecture.
&lt;/p&gt;
&lt;h5&gt;Planning for change
&lt;/h5&gt;
&lt;p&gt;
By limiting classes to one responsibility, you are also creating a class that has
only one reason to change.&amp;nbsp; As a developer who believes in Agile methodologies,
I know change is going to come.&amp;nbsp; Limiting the reasons for classes to change,
as well as the surface area in which that change will be felt, will go a long way
towards making those changes easier to implement.
&lt;/p&gt;
&lt;h2&gt;Technical
&lt;/h2&gt;
&lt;h5&gt;&lt;strong&gt;Introduces Dependencies&lt;/strong&gt;
&lt;/h5&gt;
&lt;p&gt;
Anytime you inherit from a class, you are explicitly creating a dependency on that
super class.&amp;nbsp; The code to the super class may change over time.&amp;nbsp; Each time
it does change, it can potentially directly or indirectly break some or all of its
subclasses, even though the code in subclasses may not have changed at all.&amp;nbsp;
Most likely, the subclasses had no idea the change even occurred at all.&amp;nbsp; And
unless you have planned for this contingency in your unit test (you &lt;strong&gt;are&lt;/strong&gt; writing
unit tests, right???), you may not even find this breaking change until after the
code is deployed.&amp;nbsp; And if you are writing unit tests, that's just more (seemingly
avoidable) unit tests you need to write to handle these cases.
&lt;/p&gt;
&lt;p&gt;
This creates a lot more work for the API producer.&amp;nbsp; All subclasses now will have
to be designed (and tested) to evolve in conjunction with their super classes.&amp;nbsp;
That's more code and more unit tests you now have to write and maintain.
&lt;/p&gt;
&lt;h5&gt;Fragile classes
&lt;/h5&gt;
&lt;p&gt;
Due to rules we must live with when choosing a static, compiled language, we limit
ourselves in the structuring of our API.&amp;nbsp; Anytime we define a method signature
in any class, this signature causes a ripple effect up and down the inheritance hierarchy.&amp;nbsp;
That's both good and bad.&amp;nbsp; Each base class automatically inherits the new functionality,
but guess what - it may not want to do so.&amp;nbsp; Or worse yet, it can break existing
functionality in the subclass.
&lt;/p&gt;
&lt;p&gt;
For example, introducing or changing a method signature in the base class will flow
down to every class that derives from it.&amp;nbsp; What if that subclass already has
a method defined in that class with the same name?&amp;nbsp; This will cause either: a
compilation error if the method cannot be overridden; or worse yet unexpected behavior
at runtime if the method can be overridden as the subclass implementation is now unknowingly
invoked.&amp;nbsp; Or, what about if the subclass has the same method name but a different
signature?&amp;nbsp; You will be forced to change your API in one of the classes just
to get them to compile.&amp;nbsp; The same problems manifest itself as methods are introduced
in base classes, but at least you are a probably little more aware of the potentially
breaking changes.
&lt;/p&gt;
&lt;p&gt;
Think this is a far-fetched example?&amp;nbsp; I don't.&amp;nbsp; Imagine common method names
like Execute(), Activate(), Register(), or IsAvailable(), Open(), Load(), or Save().&amp;nbsp;
All of these are all methods names that are prolific in our object models, and could
easily have much different signatures as well as potentially meaning very different
things in different contexts.
&lt;/p&gt;
&lt;p&gt;
What if the behavior introduced in a base class implementation is not desired in the
subclass?&amp;nbsp; Sorry, your S.O.L.&amp;nbsp; Good and bad, you get everything that comes
down from the base.
&lt;/p&gt;
&lt;h5&gt;Refactoring
&lt;/h5&gt;
&lt;p&gt;
Due to all the problems with carrying "API baggage", classes with deep hierarchies
are much harder to refactor.&amp;nbsp; Are you completely comfortable with the API provided
by your super class?&amp;nbsp; Because anytime you extend it, any flaws/issues/concerns
you have with it are propagated down to the subclasses.&amp;nbsp; Not only that, the flaws
now become further spread across your object model through the expanded surface area
of all of its own and now its subclasses consumers.&amp;nbsp; Composition is much more
flexible.&amp;nbsp; It has the advantage of masking, improving, or changing the API to
encapsulate the existing concerns.
&lt;/p&gt;
&lt;p&gt;
Not only that, but now you have tied yourself to this mis-matched inheritance hierarchy,
and it will be much harder to introduce a new base class if a new valid one ever presents
itself.
&lt;/p&gt;
&lt;h3&gt;Summary
&lt;/h3&gt;
&lt;p&gt;
Inheritances is one of the most powerful and most abused concepts in object-oriented
programming languages today.&amp;nbsp; True, inheritance is an easy and useful way to
provide quick code reusability across your object model.&amp;nbsp; But the drawbacks of
doing so far outweigh the short-term gains achieved.&amp;nbsp; Oftentimes the reusability
gained comes as the expense of code extensibility, maintainability, and testability.&amp;nbsp;
In the long run, ironically both producers and consumers of the API will have to do
more work to maintain the fragile inheritance hierarchy.&amp;nbsp; Favor composition over
inheritance to limit fragile inheritance hierarchies and create a much more flexible
and powerful API.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=aca76c1b-3472-4fbe-8b9a-3caa29815414" /&gt;</description>
      <comments>http://www.chrisrauber.com/blog/CommentView,guid,aca76c1b-3472-4fbe-8b9a-3caa29815414.aspx</comments>
      <category>.Net</category>
      <category>Back To Basics</category>
    </item>
    <item>
      <trackback:ping>http://www.chrisrauber.com/blog/Trackback.aspx?guid=1c78f1de-1e59-4e96-9381-6adfabda91ec</trackback:ping>
      <pingback:server>http://www.chrisrauber.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.chrisrauber.com/blog/PermaLink,guid,1c78f1de-1e59-4e96-9381-6adfabda91ec.aspx</pingback:target>
      <dc:creator>Chris Rauber</dc:creator>
      <wfw:comment>http://www.chrisrauber.com/blog/CommentView,guid,1c78f1de-1e59-4e96-9381-6adfabda91ec.aspx</wfw:comment>
      <wfw:commentRss>http://www.chrisrauber.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=1c78f1de-1e59-4e96-9381-6adfabda91ec</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The <a target="_blank" href="http://www.atlalt.net/screwturn">Atlanta ALT.Net</a> user
group is <a target="_blank" href="http://dotnet.meetup.com/134/">meeting again</a> this
Wednesday, September 24 at the <a target="_blank" href="http://www.thinkingmantavern.com/">Thinking
Man Tavern</a> in Decatur.  If you plan on attending, the organizers are asking
people to RSVP in order to get an accurate head count.  
</p>
        <p>
We are going to spend some time talking about ASP.Net MVC, but I imagine it will be
open to discussion on all topics.  Hope to see you there!
</p>
        <p>
          <iframe marginheight="0" src="http://maps.google.com/maps?ie=UTF8&amp;q=537+W.+Howard+Ave,+Decatur,+GA+30030&amp;z=14&amp;iwloc=addr&amp;ll=33.776793,-84.300327&amp;output=embed&amp;s=AARTsJqzZyLpsl8QAzgSZc4mJMimAYgJ9Q" marginwidth="0" scrolling="no" width="425" frameborder="0" height="350">
          </iframe>
          <br />
          <small>
            <a style="text-align: left; color: rgb(0, 0, 255);" href="http://maps.google.com/maps?ie=UTF8&amp;q=537+W.+Howard+Ave,+Decatur,+GA+30030&amp;z=14&amp;iwloc=addr&amp;ll=33.776793,-84.300327&amp;source=embed">View
Larger Map</a>
          </small>
        </p>
        <img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=1c78f1de-1e59-4e96-9381-6adfabda91ec" />
      </body>
      <title>Atlanta ALT.Net Meetup</title>
      <guid isPermaLink="false">http://www.chrisrauber.com/blog/PermaLink,guid,1c78f1de-1e59-4e96-9381-6adfabda91ec.aspx</guid>
      <link>http://www.chrisrauber.com/blog/2008/09/22/AtlantaALTNetMeetup.aspx</link>
      <pubDate>Mon, 22 Sep 2008 15:26:11 GMT</pubDate>
      <description>&lt;p&gt;
The &lt;a target="_blank" href="http://www.atlalt.net/screwturn"&gt;Atlanta ALT.Net&lt;/a&gt; user
group is &lt;a target="_blank" href="http://dotnet.meetup.com/134/"&gt;meeting again&lt;/a&gt; this
Wednesday, September 24 at the &lt;a target="_blank" href="http://www.thinkingmantavern.com/"&gt;Thinking
Man Tavern&lt;/a&gt; in Decatur.&amp;nbsp; If you plan on attending, the organizers are asking
people to RSVP in order to get an accurate head count.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
We are going to spend some time talking about ASP.Net MVC, but I imagine it will be
open to discussion on all topics.&amp;nbsp; Hope to see you there!
&lt;/p&gt;
&lt;p&gt;
&lt;iframe marginheight="0" src="http://maps.google.com/maps?ie=UTF8&amp;amp;q=537+W.+Howard+Ave,+Decatur,+GA+30030&amp;amp;z=14&amp;amp;iwloc=addr&amp;amp;ll=33.776793,-84.300327&amp;amp;output=embed&amp;amp;s=AARTsJqzZyLpsl8QAzgSZc4mJMimAYgJ9Q" marginwidth="0" scrolling="no" width="425" frameborder="0" height="350"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;small&gt;&lt;a style="text-align: left; color: rgb(0, 0, 255);" href="http://maps.google.com/maps?ie=UTF8&amp;amp;q=537+W.+Howard+Ave,+Decatur,+GA+30030&amp;amp;z=14&amp;amp;iwloc=addr&amp;amp;ll=33.776793,-84.300327&amp;amp;source=embed"&gt;View
Larger Map&lt;/a&gt;&lt;/small&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=1c78f1de-1e59-4e96-9381-6adfabda91ec" /&gt;</description>
      <comments>http://www.chrisrauber.com/blog/CommentView,guid,1c78f1de-1e59-4e96-9381-6adfabda91ec.aspx</comments>
      <category>.Net</category>
      <category>alt.net</category>
    </item>
    <item>
      <trackback:ping>http://www.chrisrauber.com/blog/Trackback.aspx?guid=f119c53f-35ef-443a-9009-8b7f49e66930</trackback:ping>
      <pingback:server>http://www.chrisrauber.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.chrisrauber.com/blog/PermaLink,guid,f119c53f-35ef-443a-9009-8b7f49e66930.aspx</pingback:target>
      <dc:creator>Chris Rauber</dc:creator>
      <wfw:comment>http://www.chrisrauber.com/blog/CommentView,guid,f119c53f-35ef-443a-9009-8b7f49e66930.aspx</wfw:comment>
      <wfw:commentRss>http://www.chrisrauber.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=f119c53f-35ef-443a-9009-8b7f49e66930</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
My friend <a href="http://boorad.weebly.com/index.html" target="_blank">Brad Anderson</a> is
putting together a meetup for the <a href="http://groups.google.com/group/maeug" target="_blank">Metro
Atlanta Erlang Users Group</a>.  They are planning their <a href="http://boorad.weebly.com/1/post/2008/09/atlanta-erlang-meetup.html" target="_blank">initial
meeting</a> to be at <a href="http://www.brickstorepub.com/home/" target="_blank">The
Brick Store Pub</a> in <a href="http://maps.google.com/maps?q=125%20East%20court%20street%2C%20Decatur%2C%20GA&amp;ie=UTF-8&amp;oe=utf-8&amp;rls=org.mozilla:en-US:official&amp;client=firefox-a&amp;um=1&amp;sa=N&amp;tab=wl" target="_blank">downtown
Decatur</a> this Saturday (September 20th) at 7pm.  
</p>
        <p>
Unfortunately, I am probably not going to be able to make it since it's my anniversary
weekend, but if you are at all interested in <a href="http://www.erlang.org/" target="_blank">Erlang</a> (or
functional languages of any sort), it should be a good time.  He told me people
are coming from as far away as Raleigh just for this meetup.  And if you enjoy
good beer (who doesn't???), it doesn't get much better than the Brick Store.
</p>
        <img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=f119c53f-35ef-443a-9009-8b7f49e66930" />
      </body>
      <title>Atlanta Erlang Meetup</title>
      <guid isPermaLink="false">http://www.chrisrauber.com/blog/PermaLink,guid,f119c53f-35ef-443a-9009-8b7f49e66930.aspx</guid>
      <link>http://www.chrisrauber.com/blog/2008/09/19/AtlantaErlangMeetup.aspx</link>
      <pubDate>Fri, 19 Sep 2008 03:08:02 GMT</pubDate>
      <description>&lt;p&gt;
My friend &lt;a href="http://boorad.weebly.com/index.html" target="_blank"&gt;Brad Anderson&lt;/a&gt; is
putting together a meetup for the &lt;a href="http://groups.google.com/group/maeug" target="_blank"&gt;Metro
Atlanta Erlang Users Group&lt;/a&gt;.&amp;nbsp; They are planning their &lt;a href="http://boorad.weebly.com/1/post/2008/09/atlanta-erlang-meetup.html" target="_blank"&gt;initial
meeting&lt;/a&gt; to be at &lt;a href="http://www.brickstorepub.com/home/" target="_blank"&gt;The
Brick Store Pub&lt;/a&gt; in &lt;a href="http://maps.google.com/maps?q=125%20East%20court%20street%2C%20Decatur%2C%20GA&amp;amp;ie=UTF-8&amp;amp;oe=utf-8&amp;amp;rls=org.mozilla:en-US:official&amp;amp;client=firefox-a&amp;amp;um=1&amp;amp;sa=N&amp;amp;tab=wl" target="_blank"&gt;downtown
Decatur&lt;/a&gt; this Saturday (September 20th) at 7pm.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Unfortunately, I am probably not going to be able to make it since it's my anniversary
weekend, but if you are at all interested in &lt;a href="http://www.erlang.org/" target="_blank"&gt;Erlang&lt;/a&gt; (or
functional languages of any sort), it should be a good time.&amp;nbsp; He told me people
are coming from as far away as Raleigh just for this meetup.&amp;nbsp; And if you enjoy
good beer (who doesn't???), it doesn't get much better than the Brick Store.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=f119c53f-35ef-443a-9009-8b7f49e66930" /&gt;</description>
      <comments>http://www.chrisrauber.com/blog/CommentView,guid,f119c53f-35ef-443a-9009-8b7f49e66930.aspx</comments>
      <category>Erlang</category>
      <category>Programming</category>
    </item>
    <item>
      <trackback:ping>http://www.chrisrauber.com/blog/Trackback.aspx?guid=9fb7b8a3-2834-46d4-bcde-5c94540bd4aa</trackback:ping>
      <pingback:server>http://www.chrisrauber.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.chrisrauber.com/blog/PermaLink,guid,9fb7b8a3-2834-46d4-bcde-5c94540bd4aa.aspx</pingback:target>
      <dc:creator>Chris Rauber</dc:creator>
      <wfw:comment>http://www.chrisrauber.com/blog/CommentView,guid,9fb7b8a3-2834-46d4-bcde-5c94540bd4aa.aspx</wfw:comment>
      <wfw:commentRss>http://www.chrisrauber.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=9fb7b8a3-2834-46d4-bcde-5c94540bd4aa</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In my last post, I showed <a href="http://www.chrisrauber.com/blog/2008/08/08/UsingTempDirectoriesInNet.aspx" target="_blank">how
to write stuff out to a temporary directory</a>.  After I wrote the post, I started
thinking about how people could misconstrue the meaning of it.  The post was
intended to show how to dump stuff easily to a random directory on the file system. 
The code that drove me to write that particular example came from a unit test that
was using the temporary directory as a repository for the output of the <span style="font-family: monospace">XmlSerializer</span>. 
In other words, I really was not doing anything meaningful with the data.
</p>
        <p>
To clear things up, I thought I would write a post that showed how use a unknown storage
directory as a <strong>meaningful</strong> repository for application data. 
What constitutes meaningful data?  I don't know, it's your app!!!  But common
possibilities include application settings, user-specific data, etc...  I'm thinking
of things that might be otherwise be stored in the registry.  Yeah, don't do
that anymore.  I don't know about you, but the just the word "registry" causes
me to shudder.
</p>
        <p>
.Net has introduced a new concept called "Isolated Storage" to hold this type of information. 
Isolated storage is an unspecified location on the file system that is hidden away
from the application.  Even though the location is unknown, the application is
guaranteed to have full permissions to it, even if it is running in a restricted security
mode.  As it name implies, the location is "isolated" so that any data written
to it does not affect other applications or anything else on the file system. 
So as far as security goes, you're limited to only hurting yourself by maliciously
or ignorantly (mis)using this repository.
</p>
        <p>
Here's a code sample of how you would use it to store data:
</p>
        <pre class="c-sharp" name="code">// get the location specific to this user/assembly
IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForAssembly();
// create a file to write the data to 
using ( var outStream = new IsolatedStorageFileStream("foo.txt", FileMode.Create, isf) ) 
{
    using ( var sw = new StreamWriter(outStream) ) 
    {
    	// write out the text
        sw.Write("Random text");
        sw.Close();
    }
}</pre>
        <p>
And here is how you can retrieve it:
</p>
        <pre class="c-sharp" name="code">IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForAssembly();
// open the file
using ( var inStream = new IsolatedStorageFileStream("foo.txt", FileMode.Open, isf) ) 
{
    string[] files = isf.GetFileNames("foo.txt");
    if ( files.length &gt; 0 )
    {
        StringBuilder sb = new StringBuilder();
        foreach ( var file in files )
        {
            using ( var sr = new StreamReader(inStream) )
            {
                sb.AppendLine(sr.ReadLine());
            }
        }
    }
}</pre>
        <p>
This method is a much more "enterprise-y" way to access data in your applications.
</p>
        <img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=9fb7b8a3-2834-46d4-bcde-5c94540bd4aa" />
      </body>
      <title>Isolated Storage</title>
      <guid isPermaLink="false">http://www.chrisrauber.com/blog/PermaLink,guid,9fb7b8a3-2834-46d4-bcde-5c94540bd4aa.aspx</guid>
      <link>http://www.chrisrauber.com/blog/2008/08/09/IsolatedStorage.aspx</link>
      <pubDate>Sat, 09 Aug 2008 20:45:26 GMT</pubDate>
      <description>&lt;p&gt;
In my last post, I showed &lt;a href="http://www.chrisrauber.com/blog/2008/08/08/UsingTempDirectoriesInNet.aspx" target="_blank"&gt;how
to write stuff out to a temporary directory&lt;/a&gt;.&amp;nbsp; After I wrote the post, I started
thinking about how people could misconstrue the meaning of it.&amp;nbsp; The post was
intended to show how to dump stuff easily to a random directory on the file system.&amp;nbsp;
The code that drove me to write that particular example came from a unit test that
was using the temporary directory as a repository for the output of the &lt;span style="font-family: monospace"&gt;XmlSerializer&lt;/span&gt;.&amp;nbsp;
In other words, I really was not doing anything meaningful with the data.
&lt;/p&gt;
&lt;p&gt;
To clear things up, I thought I would write a post that showed how use a unknown storage
directory as a &lt;strong&gt;meaningful&lt;/strong&gt; repository for application data.&amp;nbsp;
What constitutes meaningful data?&amp;nbsp; I don't know, it's your app!!!&amp;nbsp; But common
possibilities include application settings, user-specific data, etc...&amp;nbsp; I'm thinking
of things that might be otherwise be stored in the registry.&amp;nbsp; Yeah, don't do
that anymore.&amp;nbsp; I don't know about you, but the just the word "registry" causes
me to shudder.
&lt;/p&gt;
&lt;p&gt;
.Net has introduced a new concept called "Isolated Storage" to hold this type of information.&amp;nbsp;
Isolated storage is an unspecified location on the file system that is hidden away
from the application.&amp;nbsp; Even though the location is unknown, the application is
guaranteed to have full permissions to it, even if it is running in a restricted security
mode.&amp;nbsp; As it name implies, the location is "isolated" so that any data written
to it does not affect other applications or anything else on the file system.&amp;nbsp;
So as far as security goes, you're limited to only hurting yourself by maliciously
or ignorantly (mis)using this repository.
&lt;/p&gt;
&lt;p&gt;
Here's a code sample of how you would use it to store data:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;// get the location specific to this user/assembly
IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForAssembly();
// create a file to write the data to 
using ( var outStream = new IsolatedStorageFileStream("foo.txt", FileMode.Create, isf) ) 
{
    using ( var sw = new StreamWriter(outStream) ) 
    {
    	// write out the text
        sw.Write("Random text");
        sw.Close();
    }
}&lt;/pre&gt;
&lt;p&gt;
And here is how you can retrieve it:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForAssembly();
// open the file
using ( var inStream = new IsolatedStorageFileStream("foo.txt", FileMode.Open, isf) ) 
{
    string[] files = isf.GetFileNames("foo.txt");
    if ( files.length &amp;gt; 0 )
    {
        StringBuilder sb = new StringBuilder();
        foreach ( var file in files )
        {
            using ( var sr = new StreamReader(inStream) )
            {
                sb.AppendLine(sr.ReadLine());
            }
        }
    }
}&lt;/pre&gt;
&lt;p&gt;
This method is a much more "enterprise-y" way to access data in your applications.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=9fb7b8a3-2834-46d4-bcde-5c94540bd4aa" /&gt;</description>
      <comments>http://www.chrisrauber.com/blog/CommentView,guid,9fb7b8a3-2834-46d4-bcde-5c94540bd4aa.aspx</comments>
      <category>.Net</category>
      <category>C#</category>
    </item>
    <item>
      <trackback:ping>http://www.chrisrauber.com/blog/Trackback.aspx?guid=bcb94234-0422-46ba-adf6-69370db98ff8</trackback:ping>
      <pingback:server>http://www.chrisrauber.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.chrisrauber.com/blog/PermaLink,guid,bcb94234-0422-46ba-adf6-69370db98ff8.aspx</pingback:target>
      <dc:creator>Chris Rauber</dc:creator>
      <wfw:comment>http://www.chrisrauber.com/blog/CommentView,guid,bcb94234-0422-46ba-adf6-69370db98ff8.aspx</wfw:comment>
      <wfw:commentRss>http://www.chrisrauber.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=bcb94234-0422-46ba-adf6-69370db98ff8</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Have you ever found the need to use a temporary directory on the file system in your
code?  This issue came up with me recently (and bit me in the ass), so I thought
I would share some experiences on how I overcame the problem.  
</p>
        <p>
At the root of the problem is that you need some sort of permanent storage, but nothing
that is stringent enough to require it reside in some "known" directory where it can
be accessed at a later time.  You don't really care where you store a file, but
you need to store it somewhere.  
</p>
        <p>
I recently came across a piece of code in a unit test that serialized a class using
the XmlSerializer.  The person who wrote the test must have wanted to see what
the class looked like in serialized form.  The code was written so that the xml
version of the class was dumped to the file system.  However, when the test was
written, the file was hard-coded to the C:\Temp directory.  
</p>
        <p>
As part of my task, I was incorporating the unit tests on this component into the
continuous build.  Guess what happened when the test was moved the build server? 
FAIL!!!  No C:\Temp directory on that machine means lots of red on the build
server and the IT director screaming WTF?!?!?
</p>
        <p>
The lesson is, never make assumptions when accessing the file system.  In this
case, the test was counting on the directory both existing and the user having permissions
to it.  Obviously, that's not a good idea.
</p>
        <p>
There are other ways to get to a valid "temporary" directory in .Net.  The following
code sample shows how you can try a few known places in .Net that should work as "temporary"
directories.
</p>
        <pre class="c-sharp" name="code">/// &lt;summary&gt;
/// Get a valid "temporary" directory on the machine that is running this code 
/// &lt;/summary&gt;
/// &lt;returns&gt;a temporary directory&lt;/returns&gt;
private string GetTemporaryDirectory() 
{ 
    // try this first 
    string dir = Path.GetTempPath(); 
    if ( String.IsNullOrEmpty(dir) || !Directory.Exists(dir) ) 
    { 
        // see if the "TEMP" environment variable is set 
        dir = Environment.GetEnvironmentVariable("TEMP"); 
        if ( String.IsNullOrEmpty(dir) || !Directory.Exists(dir) ) 
        { 
            // hmmm ... let's create one in "My Documents" 
            string myDocsDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); 
            if ( String.IsNullOrEmpty(myDocsDir) || !Directory.Exists(myDocsDir) ) 
            { 
                // no "My Documents" directory??? 
                throw new Exception( 
                    "Cannot determine a valid temporary directory on this system. " + 
                    "Please set a valid directory for the \"TEMP\" environment variable."); 
            } 
            dir = String.Format("{0}\\Temp", myDocsDir); 
            if ( !Directory.Exists(dir) ) 
            { 
                Log.Info("Creating new Temp directory in {0}", myDocsDir); 
                Directory.CreateDirectory(dir); 
            }  
        } 
    } 
    if ( dir.EndsWith("\\") ) 
    { 
        // cut the last char off 
        dir = dir.Substring(0, dir.Length - 1); 
    } 
    return dir; 
}</pre>
        <p>
The code example above tries to use the .Net libraries to query the file system for
some well-known directories that can be used for temporary files.  If a valid
one is not found, it will try to create a "Temp" directory in the current user's "My
Documents" directory.  At worst, the user should have access to this directory,
and the build should not break based on a hard-coded assumption.
</p>
        <img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=bcb94234-0422-46ba-adf6-69370db98ff8" />
      </body>
      <title>Using Temp directories in .Net</title>
      <guid isPermaLink="false">http://www.chrisrauber.com/blog/PermaLink,guid,bcb94234-0422-46ba-adf6-69370db98ff8.aspx</guid>
      <link>http://www.chrisrauber.com/blog/2008/08/08/UsingTempDirectoriesInNet.aspx</link>
      <pubDate>Fri, 08 Aug 2008 05:46:30 GMT</pubDate>
      <description>&lt;p&gt;
Have you ever found the need to use a temporary directory on the file system in your
code?&amp;nbsp; This issue came up with me recently (and bit me in the ass), so I thought
I would share some experiences on how I overcame the problem.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
At the root of the problem is that you need some sort of permanent storage, but nothing
that is stringent enough to require it reside in some "known" directory where it can
be accessed at a later time.&amp;nbsp; You don't really care where you store a file, but
you need to store it somewhere.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
I recently came across a piece of code in a unit test that serialized a class using
the XmlSerializer.&amp;nbsp; The person who wrote the test must have wanted to see what
the class looked like in serialized form.&amp;nbsp; The code was written so that the xml
version of the class was dumped to the file system.&amp;nbsp; However, when the test was
written, the file was hard-coded to the C:\Temp directory.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
As part of my task, I was incorporating the unit tests on this component into the
continuous build.&amp;nbsp; Guess what happened when the test was moved the build server?&amp;nbsp;
FAIL!!!&amp;nbsp; No C:\Temp directory on that machine means lots of red on the build
server and the IT director screaming WTF?!?!?
&lt;/p&gt;
&lt;p&gt;
The lesson is, never make assumptions when accessing the file system.&amp;nbsp; In this
case, the test was counting on the directory both existing and the user having permissions
to it.&amp;nbsp; Obviously, that's not a good idea.
&lt;/p&gt;
&lt;p&gt;
There are other ways to get to a valid "temporary" directory in .Net.&amp;nbsp; The following
code sample shows how you can try a few known places in .Net that should work as "temporary"
directories.
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;/// &amp;lt;summary&amp;gt;
/// Get a valid "temporary" directory on the machine that is running this code 
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;returns&amp;gt;a temporary directory&amp;lt;/returns&amp;gt;
private string GetTemporaryDirectory() 
{ 
    // try this first 
    string dir = Path.GetTempPath(); 
    if ( String.IsNullOrEmpty(dir) || !Directory.Exists(dir) ) 
    { 
        // see if the "TEMP" environment variable is set 
        dir = Environment.GetEnvironmentVariable("TEMP"); 
        if ( String.IsNullOrEmpty(dir) || !Directory.Exists(dir) ) 
        { 
            // hmmm ... let's create one in "My Documents" 
            string myDocsDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); 
            if ( String.IsNullOrEmpty(myDocsDir) || !Directory.Exists(myDocsDir) ) 
            { 
                // no "My Documents" directory??? 
                throw new Exception( 
                    "Cannot determine a valid temporary directory on this system. " + 
                    "Please set a valid directory for the \"TEMP\" environment variable."); 
            } 
            dir = String.Format("{0}\\Temp", myDocsDir); 
            if ( !Directory.Exists(dir) ) 
            { 
                Log.Info("Creating new Temp directory in {0}", myDocsDir); 
                Directory.CreateDirectory(dir); 
            }  
        } 
    } 
    if ( dir.EndsWith("\\") ) 
    { 
        // cut the last char off 
        dir = dir.Substring(0, dir.Length - 1); 
    } 
    return dir; 
}&lt;/pre&gt;
&lt;p&gt;
The code example above tries to use the .Net libraries to query the file system for
some well-known directories that can be used for temporary files.&amp;nbsp; If a valid
one is not found, it will try to create a "Temp" directory in the current user's "My
Documents" directory.&amp;nbsp; At worst, the user should have access to this directory,
and the build should not break based on a hard-coded assumption.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=bcb94234-0422-46ba-adf6-69370db98ff8" /&gt;</description>
      <comments>http://www.chrisrauber.com/blog/CommentView,guid,bcb94234-0422-46ba-adf6-69370db98ff8.aspx</comments>
      <category>.Net</category>
      <category>C#</category>
    </item>
    <item>
      <trackback:ping>http://www.chrisrauber.com/blog/Trackback.aspx?guid=2ce1a8aa-4739-4796-bd26-ce43dcd16df9</trackback:ping>
      <pingback:server>http://www.chrisrauber.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.chrisrauber.com/blog/PermaLink,guid,2ce1a8aa-4739-4796-bd26-ce43dcd16df9.aspx</pingback:target>
      <dc:creator>Chris Rauber</dc:creator>
      <wfw:comment>http://www.chrisrauber.com/blog/CommentView,guid,2ce1a8aa-4739-4796-bd26-ce43dcd16df9.aspx</wfw:comment>
      <wfw:commentRss>http://www.chrisrauber.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=2ce1a8aa-4739-4796-bd26-ce43dcd16df9</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Take a look at this little announcement that came out of OSCON last week...
</p>
        <p>
          <a title="http://port25.technet.com/archive/2008/07/25/oscon2008.aspx" href="http://port25.technet.com/archive/2008/07/25/oscon2008.aspx">http://port25.technet.com/archive/2008/07/25/oscon2008.aspx</a>
        </p>
        <p>
Amazingly, Microsoft has agreed to join the <a href="http://www.apache.org/" target="_blank">Apache
Software Foundation</a> as a <a href="http://www.apache.org/foundation/sponsorship.html" target="_blank">platinum
sponsor</a>.  Oh, in case you weren't aware, Microsoft has this little product
called <a href="http://www.iis.net/" target="_blank">"IIS"</a> that <strike>kind of</strike> directly
competes against the open-source Apache web server.
</p>
        <p>
Paradoxically, IIS would die to get the market share enjoyed by Apache, yet is neither
free as in beer nor as in speech.  A fact that I imagine probably makes for a
tough sell for the Microsoft marketing department.
</p>
        <p>
The cynics are saying this is a bold move by Microsoft to help ease the sting caused
by the PR fiasco known as "Windows Vista."
</p>
        <p>
"Hey, look at us, you might <strong>think</strong> we suck and are inherently evil,
but suddenly we <strong>love</strong> open source (well, not anything that is <a href="http://www.gnu.org/licenses/gpl.html" target="_blank">GPL</a>'ed
- but I guess that's just common sense)."  
</p>
        <p>
I honestly don't know what to make of it.  I guess in the grand scheme of things,
the $100,000 ponied up to join Apache can't even be considered a drop in the bucket
for Microsoft.  As they said on <a href="http://twit.tv/twit" target="_blank">TWiT</a> this
last weekend, "That just gets them on the mailing list."
</p>
        <p>
Maybe it's like <a href="http://en.wikipedia.org/wiki/Sun_Tzu" target="_blank">Sun-Tzu</a> said
(and later echoed by <a href="http://us.imdb.com/character/ch0000790/" target="_blank">Michael
Coreleone</a> in <a href="http://us.imdb.com/title/tt0071562/" target="_blank">Godfather
II</a>), "Keep your friends close, but your enemies even closer." 
</p>
        <img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=2ce1a8aa-4739-4796-bd26-ce43dcd16df9" />
      </body>
      <title>Is MS-Linux next???</title>
      <guid isPermaLink="false">http://www.chrisrauber.com/blog/PermaLink,guid,2ce1a8aa-4739-4796-bd26-ce43dcd16df9.aspx</guid>
      <link>http://www.chrisrauber.com/blog/2008/07/30/IsMSLinuxNext.aspx</link>
      <pubDate>Wed, 30 Jul 2008 03:01:31 GMT</pubDate>
      <description>&lt;p&gt;
Take a look at this little announcement that came out of OSCON last week...
&lt;/p&gt;
&lt;p&gt;
&lt;a title="http://port25.technet.com/archive/2008/07/25/oscon2008.aspx" href="http://port25.technet.com/archive/2008/07/25/oscon2008.aspx"&gt;http://port25.technet.com/archive/2008/07/25/oscon2008.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Amazingly, Microsoft has agreed to join the &lt;a href="http://www.apache.org/" target="_blank"&gt;Apache
Software Foundation&lt;/a&gt; as a &lt;a href="http://www.apache.org/foundation/sponsorship.html" target="_blank"&gt;platinum
sponsor&lt;/a&gt;.&amp;nbsp; Oh, in case you weren't aware, Microsoft has this little product
called &lt;a href="http://www.iis.net/" target="_blank"&gt;"IIS"&lt;/a&gt; that &lt;strike&gt;kind of&lt;/strike&gt; directly
competes against the open-source Apache web server.
&lt;/p&gt;
&lt;p&gt;
Paradoxically, IIS would die to get the market share enjoyed by Apache, yet is neither
free as in beer nor as in speech.&amp;nbsp; A fact that I imagine probably makes for a
tough sell for the Microsoft marketing department.
&lt;/p&gt;
&lt;p&gt;
The cynics are saying this is a bold move by Microsoft to help ease the sting caused
by the PR fiasco known as "Windows Vista."
&lt;/p&gt;
&lt;p&gt;
"Hey, look at us, you might &lt;strong&gt;think&lt;/strong&gt; we suck and are inherently evil,
but suddenly we &lt;strong&gt;love&lt;/strong&gt; open source (well, not anything that is &lt;a href="http://www.gnu.org/licenses/gpl.html" target="_blank"&gt;GPL&lt;/a&gt;'ed
- but I guess that's just common sense)."&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
I honestly don't know what to make of it.&amp;nbsp; I guess in the grand scheme of things,
the $100,000 ponied up to join Apache can't even be considered a drop in the bucket
for Microsoft.&amp;nbsp; As they said on &lt;a href="http://twit.tv/twit" target="_blank"&gt;TWiT&lt;/a&gt; this
last weekend, "That just gets them on the mailing list."
&lt;/p&gt;
&lt;p&gt;
Maybe it's like &lt;a href="http://en.wikipedia.org/wiki/Sun_Tzu" target="_blank"&gt;Sun-Tzu&lt;/a&gt; said
(and later echoed by &lt;a href="http://us.imdb.com/character/ch0000790/" target="_blank"&gt;Michael
Coreleone&lt;/a&gt; in &lt;a href="http://us.imdb.com/title/tt0071562/" target="_blank"&gt;Godfather
II&lt;/a&gt;), "Keep your friends close, but your enemies even closer." 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=2ce1a8aa-4739-4796-bd26-ce43dcd16df9" /&gt;</description>
      <comments>http://www.chrisrauber.com/blog/CommentView,guid,2ce1a8aa-4739-4796-bd26-ce43dcd16df9.aspx</comments>
      <category>.Net</category>
      <category>Apache</category>
      <category>IIS</category>
      <category>Open Source</category>
    </item>
    <item>
      <trackback:ping>http://www.chrisrauber.com/blog/Trackback.aspx?guid=8633dac3-4811-465e-b4cd-05de6c44e2d3</trackback:ping>
      <pingback:server>http://www.chrisrauber.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.chrisrauber.com/blog/PermaLink,guid,8633dac3-4811-465e-b4cd-05de6c44e2d3.aspx</pingback:target>
      <dc:creator>Chris Rauber</dc:creator>
      <wfw:comment>http://www.chrisrauber.com/blog/CommentView,guid,8633dac3-4811-465e-b4cd-05de6c44e2d3.aspx</wfw:comment>
      <wfw:commentRss>http://www.chrisrauber.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=8633dac3-4811-465e-b4cd-05de6c44e2d3</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The first(?) meeting of the <a href="http://atlalt.net/screwturn/default.aspx" target="_blank">Atlanta
alt.net user group</a> is going to take place this Wednesday at the <a href="http://www.thinkingmantavern.com/" target="_blank">Thinking
Man's Tavern</a> in Decatur (which is conveniently located fairly close to my house). 
I have already <a href="http://dotnet.meetup.com/134/calendar/8336478/" target="_blank">RSVP''d</a>. 
If you want to come, sign up soon.  The web signup page says there are only 2
spots left.  Hope to see you there!
</p>
        <img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=8633dac3-4811-465e-b4cd-05de6c44e2d3" />
      </body>
      <title>Atlanta alt.net user group meetup</title>
      <guid isPermaLink="false">http://www.chrisrauber.com/blog/PermaLink,guid,8633dac3-4811-465e-b4cd-05de6c44e2d3.aspx</guid>
      <link>http://www.chrisrauber.com/blog/2008/07/20/AtlantaAltnetUserGroupMeetup.aspx</link>
      <pubDate>Sun, 20 Jul 2008 12:07:43 GMT</pubDate>
      <description>&lt;p&gt;
The first(?) meeting of the &lt;a href="http://atlalt.net/screwturn/default.aspx" target="_blank"&gt;Atlanta
alt.net user group&lt;/a&gt; is going to take place this Wednesday at the &lt;a href="http://www.thinkingmantavern.com/" target="_blank"&gt;Thinking
Man's Tavern&lt;/a&gt; in Decatur (which is conveniently located fairly close to my house).&amp;nbsp;
I have already &lt;a href="http://dotnet.meetup.com/134/calendar/8336478/" target="_blank"&gt;RSVP''d&lt;/a&gt;.&amp;nbsp;
If you want to come, sign up soon.&amp;nbsp; The web signup page says there are only 2
spots left.&amp;nbsp; Hope to see you there!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=8633dac3-4811-465e-b4cd-05de6c44e2d3" /&gt;</description>
      <comments>http://www.chrisrauber.com/blog/CommentView,guid,8633dac3-4811-465e-b4cd-05de6c44e2d3.aspx</comments>
      <category>.Net</category>
      <category>alt.net</category>
    </item>
    <item>
      <trackback:ping>http://www.chrisrauber.com/blog/Trackback.aspx?guid=2b0cc41c-f9b5-46fd-a2a3-7f0fde334fa8</trackback:ping>
      <pingback:server>http://www.chrisrauber.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.chrisrauber.com/blog/PermaLink,guid,2b0cc41c-f9b5-46fd-a2a3-7f0fde334fa8.aspx</pingback:target>
      <dc:creator>Chris Rauber</dc:creator>
      <wfw:comment>http://www.chrisrauber.com/blog/CommentView,guid,2b0cc41c-f9b5-46fd-a2a3-7f0fde334fa8.aspx</wfw:comment>
      <wfw:commentRss>http://www.chrisrauber.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=2b0cc41c-f9b5-46fd-a2a3-7f0fde334fa8</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I ran into a piece of code today similar to this:
</p>
        <pre class="c-sharp" name="code">public class Base
{
    public Base()
    {
        this.Initialize();
    }

    protected virtual void Initialize()
    {
        Debug.WriteLine("Base.Initialize()");
    }
}

public class Derived : Base
{
    public Derived() : base() {}

    protected override void Initialize()
    {
        base.Initialize();
    }
}

public class FurtherDerived : Derived
{
    public FurtherDerived() : base() {}

    protected override void Initialize()
    {
        Debug.WriteLine("FurtherDerived.Initialize()");
    }
}

public class Tester
{
    public static void Main(string[] args)
    {
        Base myBase = new Base();

        Derived myDerived = new Derived();

        FurtherDerived myFurtherDerived = new FurtherDerived();

        Console.ReadLine();
    }
}</pre>
        <p>
See any problems here?  Even though the compiler lets you call virtual methods
from a base constructor, it's generally a "bad idea".  That's because the constructor
in the derived classes defers its construction up to its base classes before it executes
its own constructor (even if we don't explicitly call the base constructor like in
the example).  Yet the call to a virtual function in the base class constructor
is executed in the derived class implementation.  This can cause subtle, unexpected
problems.
</p>
        <p>
In the example above, things "happen" to go well.  It actually runs just fine. 
It outputs the following as you'd probably expect:
</p>
        <pre style="border: 1px solid rgb(51, 51, 51); color: #00FF00; background-color: Black; padding: 5px 5px 5px 5px;">Base.Initialize()
Base.Initialize()
FurtherDerived.Initialize()</pre>
        <p>
But that's only because we didn't do anything significant in the derived constructors. 
What happens if we change the FurtherDerived class:
</p>
        <pre class="c-sharp" name="code">public class FurtherDerived : Derived
{
    StringBuilder _sb;

    public FurtherDerived() : base()
    {
        _sb = new StringBuilder();
    }

    protected override void Initialize()
    {
       _sb.Append("FurtherDerived.Initialize()");
       Debug.WriteLine(_sb.ToString());
    }
}
</pre>
        <p>
Guess what happens when we run this code? FAIL!!! The dreaded, "Object reference not
set to a reference of an object". Since the <span style="font-family: monospace;">Initialize()</span> method
in the <span style="font-family: monospace;">FurtherDerived</span> class is called
from the <span style="font-family: monospace;">Base</span> constructor, we are trying
to access the <span style="font-family: monospace;">_sb</span> class level parameter
before it's ever initialized.  We are calling a method on an class we know has
not been fully constructed.  That ain't good.
</p>
        <p>
The lesson is - never call a virtual method from a constructor.  At best, you
are introducing a bug waiting to happen.  At worst, you've already done so.
</p>
        <img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=2b0cc41c-f9b5-46fd-a2a3-7f0fde334fa8" />
      </body>
      <title>Don't call virtual methods in a constructor</title>
      <guid isPermaLink="false">http://www.chrisrauber.com/blog/PermaLink,guid,2b0cc41c-f9b5-46fd-a2a3-7f0fde334fa8.aspx</guid>
      <link>http://www.chrisrauber.com/blog/2008/07/19/DontCallVirtualMethodsInAConstructor.aspx</link>
      <pubDate>Sat, 19 Jul 2008 04:57:17 GMT</pubDate>
      <description>&lt;p&gt;
I ran into a piece of code today similar to this:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;public class Base
{
    public Base()
    {
        this.Initialize();
    }

    protected virtual void Initialize()
    {
        Debug.WriteLine("Base.Initialize()");
    }
}

public class Derived : Base
{
    public Derived() : base() {}

    protected override void Initialize()
    {
        base.Initialize();
    }
}

public class FurtherDerived : Derived
{
    public FurtherDerived() : base() {}

    protected override void Initialize()
    {
        Debug.WriteLine("FurtherDerived.Initialize()");
    }
}

public class Tester
{
    public static void Main(string[] args)
    {
        Base myBase = new Base();

        Derived myDerived = new Derived();

        FurtherDerived myFurtherDerived = new FurtherDerived();

        Console.ReadLine();
    }
}&lt;/pre&gt;
&lt;p&gt;
See any problems here?&amp;nbsp; Even though the compiler lets you call virtual methods
from a base constructor, it's generally a "bad idea".&amp;nbsp; That's because the constructor
in the derived classes defers its construction up to its base classes before it executes
its own constructor (even if we don't explicitly call the base constructor like in
the example).&amp;nbsp; Yet the call to a virtual function in the base class constructor
is executed in the derived class implementation.&amp;nbsp; This can cause subtle, unexpected
problems.
&lt;/p&gt;
&lt;p&gt;
In the example above, things "happen" to go well.&amp;nbsp; It actually runs just fine.&amp;nbsp;
It outputs the following as you'd probably expect:
&lt;/p&gt;
&lt;pre style="border: 1px solid rgb(51, 51, 51); color: #00FF00; background-color: Black; padding: 5px 5px 5px 5px;"&gt;Base.Initialize()
Base.Initialize()
FurtherDerived.Initialize()&lt;/pre&gt;
&lt;p&gt;
But that's only because we didn't do anything significant in the derived constructors.&amp;nbsp;
What happens if we change the FurtherDerived class:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;public class FurtherDerived : Derived
{
    StringBuilder _sb;

    public FurtherDerived() : base()
    {
        _sb = new StringBuilder();
    }

    protected override void Initialize()
    {
       _sb.Append("FurtherDerived.Initialize()");
       Debug.WriteLine(_sb.ToString());
    }
}
&lt;/pre&gt;
&lt;p&gt;
Guess what happens when we run this code? FAIL!!! The dreaded, "Object reference not
set to a reference of an object". Since the &lt;span style="font-family: monospace;"&gt;Initialize()&lt;/span&gt; method
in the &lt;span style="font-family: monospace;"&gt;FurtherDerived&lt;/span&gt; class is called
from the &lt;span style="font-family: monospace;"&gt;Base&lt;/span&gt; constructor, we are trying
to access the &lt;span style="font-family: monospace;"&gt;_sb&lt;/span&gt; class level parameter
before it's ever initialized.&amp;nbsp; We are calling a method on an class we know has
not been fully constructed.&amp;nbsp; That ain't good.
&lt;/p&gt;
&lt;p&gt;
The lesson is - never call a virtual method from a constructor.&amp;nbsp; At best, you
are introducing a bug waiting to happen.&amp;nbsp; At worst, you've already done so.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.chrisrauber.com/blog/aggbug.ashx?id=2b0cc41c-f9b5-46fd-a2a3-7f0fde334fa8" /&gt;</description>
      <comments>http://www.chrisrauber.com/blog/CommentView,guid,2b0cc41c-f9b5-46fd-a2a3-7f0fde334fa8.aspx</comments>
      <category>.Net</category>
      <category>Back To Basics</category>
      <category>C#</category>
    </item>
  </channel>
</rss>