<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Peter Ritchie's MVP Blog : Software Development</title><link>http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx</link><description>Tags: Software Development</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Evolving code over time</title><link>http://msmvps.com/blogs/peterritchie/archive/2009/03/30/evolving-code-over-time.aspx</link><pubDate>Tue, 31 Mar 2009 04:02:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1682545</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1682545</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2009/03/30/evolving-code-over-time.aspx#comments</comments><description>&lt;p&gt;Given economics, time constraints, resource limitations, etc.; you can&amp;#39;t write all the functionality for a given solution for a single release.&amp;nbsp; Even if you weren&amp;#39;t limited by these constraints, you&amp;#39;re likely to get changing requirements as development progresses and everyone learns more about the software under development. &lt;/p&gt;
&lt;p&gt;It&amp;#39;s fairly easy to prioritize what is developed and what isn&amp;#39;t.&amp;nbsp; You simply develop only what you need (see YAGNI).&amp;nbsp; But, how do you manage adding new functionality without causing undue grief?&amp;nbsp; One way is to only make additive changes to the code.&amp;nbsp; For example, let&amp;#39;s say we have the method create CreateRequestPacket that creates a blob of bytes to send to a host over the wire: &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;public static byte[] CreateRequestPacket() &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; byte[] result = new byte[12]; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; result[0] = REQUEST_CODE; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; result[1] = NO_OPTIONAL_DATA_FLAG; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; result[2] = (byte) (result.Length - 2); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Random random = new Random(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for(int i = 3; i &amp;lt; result.Length; ++i) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = (byte) (random.Next() % byte.MaxValue); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return result; &lt;br /&gt;}&lt;/span&gt; &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In iteration x it writes out a request making certain assumptions about what the request contains.&amp;nbsp; But, in iteration y it needs to optionally include other data.&amp;nbsp; A non additive way is to simply modify CreateRequestPacket to do what is needed: &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;public static byte[] CreateRequestPacket(bool useOptionalData) &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; byte[] result = new byte[12]; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; result[0] = REQUEST_CODE; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; result[1] = OPTIONAL_DATA_FLAG; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int index = 2; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(useOptionalData) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result[index] = GetOptionalData(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ++index; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; result[index] = (byte) (result.Length - index); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Random random = new Random(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for(int i = index + 1; i &amp;lt; result.Length; ++i) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = (byte) (random.Next() % byte.MaxValue); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return result; &lt;br /&gt;}&lt;/span&gt; &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now all calls to CreateRequestPacket need to change before a build can occure and you might not be able to modify all the files that contain these calls.&amp;nbsp; So it causes undue blocking and forces you to change a number of files before you can check the file that CreateRequestPacket is contained withing. &lt;/p&gt;
&lt;p&gt;Another way of implementing this would be to implement an additive change.&amp;nbsp; That is, add a method that does what is needed and change the previous implementation to call the new method.&amp;nbsp; For example: &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;public static byte[] CreateRequestPacket(bool useOptionalData) &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; byte[] result = new byte[12]; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; result[0] = REQUEST_CODE; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; result[1] = OPTIONAL_DATA_FLAG; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int index = 2; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(useOptionalData) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result[index] = GetOptionalData(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ++index; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; result[index] = (byte) (result.Length - index); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Random random = new Random(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for(int i = index + 1; i &amp;lt; result.Length; ++i) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = (byte) (random.Next() % byte.MaxValue); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return result; &lt;br /&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;public static byte[] CreateRequestPacket() &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return CreateRequestPacket(false); &lt;br /&gt;}&lt;/span&gt; &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This allows you to check the file that contains CreateRequestPacket in right after passing unit testing and allows you to gradually change all calls to CreateRequestPacket as time permits.&lt;/p&gt;
&lt;div style="text-align:right;margin:0px;padding:4px 0px 4px 0px;" class="wlWriterHeaderFooter"&gt;&lt;a href="http://digg.com/submit?url=http%3a%2f%2fmsmvps.com%2fblogs%2fpeterritchie%2farchive%2f2009%2f03%2f28%2fevolving-code-over-time.aspx&amp;amp;title=Evolving+code+over+time."&gt;&lt;img border="0" width="100" src="http://digg.com/img/badges/100x20-digg-button.png" alt="Digg This" height="20" style="border:0;" title="Digg This" /&gt;&lt;/a&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://msmvps.com/blogs/peterritchie/archive/2009/03/28/evolving-code-over-time.aspx"&gt;&lt;img border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://msmvps.com/blogs/peterritchie/archive/2009/03/28/evolving-code-over-time.aspx&amp;amp;bgcolor=0080C0&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000" alt="DotNetKick This" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1682545" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Practices/default.aspx">Software Development Practices</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Guidance/default.aspx">Software Development Guidance</category></item><item><title>DevTeach 2009 Vancouver</title><link>http://msmvps.com/blogs/peterritchie/archive/2009/03/26/devteach-2009-vancouver.aspx</link><pubDate>Thu, 26 Mar 2009 16:33:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1681658</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1681658</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2009/03/26/devteach-2009-vancouver.aspx#comments</comments><description>&lt;p&gt;The schedule for DevTeach 2009 Vancouver has been announced (&lt;a href="http://www.devteach.com/" title="http://www.devteach.com/"&gt;http://www.devteach.com/&lt;/a&gt;).&amp;nbsp; There&amp;rsquo;s lots of great software development sessions from some of the leaders in our industry.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re planning on improving yourself, this is the conference to go to.&amp;nbsp; Not only can you attend excellent sessions; but you can hob-knob with the presenters and pick their brains.&lt;/p&gt;
&lt;p&gt;If you have a friend or co-worker who&amp;rsquo;s interested, there&amp;rsquo;s a limited-time two-for-one offer for an even better price: &lt;a href="http://www.devteach.com/Register.aspx" title="http://www.devteach.com/Register.aspx"&gt;http://www.devteach.com/Register.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fmsmvps.com%2fblogs%2fpeterritchie%2farchive%2f2009%2f03%2f26%2fdevteach-2009-vancouver.aspx"&gt;&lt;img border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fmsmvps.com%2fblogs%2fpeterritchie%2farchive%2f2009%2f03%2f26%2fdevteach-2009-vancouver.aspx" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1681658" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Visual+Studio+2005/default.aspx">Visual Studio 2005</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+2.0/default.aspx">.NET 2.0</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+3.x/default.aspx">.NET 3.x</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/DevTeach/default.aspx">DevTeach</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/DDD/default.aspx">DDD</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Practices/default.aspx">Software Development Practices</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Guidance/default.aspx">Software Development Guidance</category></item><item><title>Developing with Source Code Control - Best Practices Part 2</title><link>http://msmvps.com/blogs/peterritchie/archive/2009/03/11/developing-with-source-code-control-best-practices-part-2.aspx</link><pubDate>Wed, 11 Mar 2009 14:36:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1677545</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>13</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1677545</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2009/03/11/developing-with-source-code-control-best-practices-part-2.aspx#comments</comments><description>&lt;p&gt;&lt;span style="color:#ff0000;"&gt;[Edited 14-Mar-09: clarified generated code SCC practice]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-size:x-small;"&gt;This edition provides SCC vocabulary and some more practices that make development life easier.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:medium;"&gt;&lt;strong&gt;&lt;span style="font-size:large;"&gt;Vocabulary&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-size:x-small;"&gt;&lt;strong&gt;Trunk&lt;/strong&gt;&lt;br /&gt;The root of the project or database.&amp;nbsp; Sometimes called mainline or baseline; depending on the SCC structure, this is where most of the development occurs.&lt;br /&gt;&lt;strong&gt;Mainline&lt;/strong&gt;&lt;br /&gt;The root of the project or database.&amp;nbsp; Sometimes called trunk or baseline; depending on the SCC structure, this is where most of the development occurs.&lt;br /&gt;&lt;strong&gt;Baseline&lt;/strong&gt;&lt;br /&gt;The root of the project or database.&amp;nbsp; Sometimes called mainline or trunk; depending on the SCC structure, this is where most of the development occurs.&lt;br /&gt;&lt;strong&gt;Tag&lt;/strong&gt;&lt;br /&gt;A snapshot in time of the system or a project/subfolder in the system.&amp;nbsp; Usually also associated with an annotation explaining the significance of that point of time.&amp;nbsp; Also known as label.&lt;br /&gt;&lt;strong&gt;Label&lt;/strong&gt;&lt;br /&gt;A snapshot in time of the system or a project/subfolder in the system.&amp;nbsp; Usually also associated with an annotation explaining the significance of that point of time.&amp;nbsp; Also known as tag.&lt;br /&gt;&lt;strong&gt;Branch&lt;/strong&gt;&lt;br /&gt;A &amp;quot;copy&amp;quot; of subfolders and files that are controlled separately from the trunk with an intention to eventually merge back into the trunk.&lt;br /&gt;&lt;strong&gt;Merge&lt;/strong&gt;&lt;br /&gt;Unifies two independant changes into one.&amp;nbsp; Often the process of merging requires manual resolution of conflicts.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-size:x-small;"&gt;&lt;strong&gt;Merge Conflict&lt;br /&gt;&lt;/strong&gt;When two independant changes cannot be automatically merged.&lt;br /&gt;&lt;strong&gt;Commit&lt;/strong&gt;&lt;br /&gt;Same as check in&lt;br /&gt;&lt;strong&gt;Check in&lt;/strong&gt;&lt;br /&gt;When changes are written to the repository.&lt;br /&gt;&lt;strong&gt;Head&lt;/strong&gt;&lt;br /&gt;The most recent version of code in the system.&lt;br /&gt;&lt;strong&gt;Fork&lt;/strong&gt;&lt;br /&gt;For the most part, same as branch--depending on the SCC system.&amp;nbsp; More fun to use than branch, &amp;quot;I forked the code&amp;quot;.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:x-small;"&gt;&lt;strong&gt;Copy-modify-merge&lt;br /&gt;&lt;/strong&gt;Under this SCC model the SCC always merges changes back into the database (trunk or branch, depending on what you&amp;#39;re editing).&amp;nbsp;This model assumes a team model where there is the likely posibility of more than one person working on the same file at the same time.&amp;nbsp; This model rarely precludes the ability to lock a file before modification if changes to the file cannot be merged).&amp;nbsp; This is the preferred SCC model.&lt;br /&gt;&lt;strong&gt;Lock-modify-unlock&lt;/strong&gt;&lt;br /&gt;Under this SCC model the SCC forces devs to lock files they wish to edit before modifying them.&amp;nbsp; (with IDE integration this is often transparent).&lt;br /&gt;&lt;strong&gt;ALM&lt;/strong&gt;&lt;br /&gt;Application lifecycle management.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-size:large;"&gt;&lt;strong&gt;Practices&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-size:x-small;"&gt;&lt;strong&gt;Don&amp;#39;t use Visual SourceSafe for your SCC system.&lt;/strong&gt;&lt;br /&gt;Believe me, I&amp;#39;ve been there and have the scars to prove it.&amp;nbsp; Visual SourceSafe (VSS) has a unique process that isn&amp;#39;t mirrored by many major&amp;nbsp;contemporary SCC systems.&amp;nbsp; VSS is a distributed file-based SCC system and as such is prone to data corruption--not really something that is acceptable in any sort of &amp;quot;Control&amp;quot; system.&amp;nbsp; Branching is really difficult in VSS.&amp;nbsp; If you&amp;#39;re one person and you have your VSS database on the same computer; you&amp;#39;re likely fine.&amp;nbsp; Otherwise, do yourself a huge favour and consider another SCC system, like Subversion (it&amp;#39;s free).&amp;nbsp; VSS doesn&amp;#39;t scale well; as time goes on and the database increases in size, developers are added to the project, VSS gets slower and slower.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-size:x-small;"&gt;&lt;strong&gt;Don&amp;#39;t put generated&amp;nbsp; code in SCC&lt;br /&gt;&lt;/strong&gt;SCC provides the ability to rollback to a state in the past that allows compilation of the solution.&amp;nbsp; Code that is generated &lt;span style="color:#ff0000;"&gt;[edit start]&lt;/span&gt; as part of the/a build process &lt;span style="color:#ff0000;"&gt;[edit end]&lt;/span&gt; can be generated at any time; there&amp;#39;s no need to put that code into SCC.&amp;nbsp; With lock-modify-unlock SCC systems, generated code that is checked-in will be locked and cause errors during build unless you lock it on every build.&amp;nbsp; This will cause conflicts in lock-modify-unlock systems in that you end up not being able to build while somone else is building (yes, you likely build serveral times a day).&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-size:x-small;"&gt;&lt;strong&gt;Make sure unit tests pass before checking in.&lt;/strong&gt;&lt;br /&gt;This means *all* unit tests.&amp;nbsp; If you check in a change that causes a unit test to fail, someone else won&amp;#39;t know where to start to make that unit test pass.&amp;nbsp; You&amp;#39;re wasting your time and setting the project schedule back by not ensuring unit tests pass before checking in changes.&amp;nbsp; If your team allows it, use some sort of continuous integration suite.&amp;nbsp; This allows you to get feedback upon every check-in that tells you whether all the unit tests pass.&amp;nbsp; If you have an SCC or ALM that supports it, enable guards that force the unit tests to pass before changes are allowed into SCC.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-size:x-small;"&gt;&lt;strong&gt;Work on one set of related changes at a time.&lt;/strong&gt;&lt;br /&gt;It&amp;#39;s more efficient to work on one thing at a time.&amp;nbsp; Switching back and forth from task to task means wasting time getting into a different frame of mind and sometimes a different configuration.&amp;nbsp; This also causes issues with SCC in that you&amp;#39;ve now got modified files that you&amp;#39;re not currently working on.&amp;nbsp; The longer they&amp;#39;re kept unmerged, the more likely there will be issues during merge (someone else made a changed that conflicts with yours, and if everyone else is checking in often, you&amp;#39;re the one that has to deal with all the conflicts).&amp;nbsp; The more things you&amp;#39;re working on at once, the more likely that one set of changes becomes dependant on another and you simply can&amp;#39;t check your files in until all the changes you&amp;#39;re working on are complete.&amp;nbsp; Work on one set of related changes at a time and check those changes in to avoid not merging your changes often.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-size:x-small;"&gt;&lt;strong&gt;Check-in often.&lt;/strong&gt;&lt;br /&gt;SCC provides developers the ability to keep a history of their changes.&amp;nbsp; But, this only works if you check your changes into the SCC system.&amp;nbsp; When you have something that compiles, check it in.&amp;nbsp; The more often you check changes into the SCC system the less likely you&amp;#39;ll get into a situation where you have to deal with merge conflicts.&amp;nbsp; The more often you check changes into the SCC system the least complex the changes will be.&amp;nbsp; If the changes are not complex and you do run into a merge conflict, the less work will be involved in resolving the conflict.&amp;nbsp; Do your sanity (and the sanity of your team mates) a favour and check in often.&amp;nbsp; See next practice.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-size:x-small;"&gt;&lt;strong&gt;Avoid leaving changes overnight.&lt;/strong&gt;&lt;br /&gt;Check in your working&amp;nbsp;changes before you leave for the day.&amp;nbsp; If it compiles and works (unit tests pass) there&amp;#39;s likely no harm to checking in.&amp;nbsp; Leaving work for an extended period of time means it&amp;#39;s that much harder to get back into that mindset; if you check in and describe the check in, you now have a history of the day&amp;#39;s changes with an annotation making it easier to get back in that mindset.&amp;nbsp; But, since you&amp;#39;ve checked the files in, you may not need to get back into that mindset (if you didn&amp;#39;t check in, you *must* get back in that mindset in order to check in).&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-size:x-small;"&gt;&lt;strong&gt;Never destroy SCC content.&lt;/strong&gt;&lt;br /&gt;SCC offers the ability to get back to a project state at any time in the past.&amp;nbsp; If you destroy content from the system, this incapacitates this ability.&amp;nbsp; It goes against keeping any sort of history of a project to destroy content, so don&amp;#39;t do it unless you intend never to make use of the history for that project (i.e. you&amp;#39;re destroying and entire project and you never intend to work on it again or support it).&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-size:x-small;"&gt;&lt;strong&gt;Don&amp;#39;t Bypass Copy-modify-Merge&lt;/strong&gt;&lt;br /&gt;Eventually you&amp;#39;ll be in a situation where you need to edit a file at the same time as another person.&amp;nbsp; In this case you&amp;#39;ll need to merge your changes.&amp;nbsp; The copy-modify-merge model accepts this inevitable fact and makes merging a first-class citizen of your development process; not some nebulous process that occurs only occaisionally.&amp;nbsp; With a properly designed system the need to merge should be minimized.&amp;nbsp; I&amp;#39;ve seen teams instigate a policy that you must lock the file before you modify it.&amp;nbsp; I&amp;#39;ve also seen teams configure a SCC provider to automatically lock a file when changes are made to it.&amp;nbsp; This is the wrong thing to do on software development teams.&amp;nbsp; It leads to one of two things: 1) people just stop working when they can&amp;#39;t lock the file they need to edit; or 2) they end up forcing copy-modify-merge that isn&amp;#39;t supported by the tools they&amp;#39;re using, which often leads to human errors and errors in merging.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-size:x-small;"&gt;I hope to continue this series as time goes on, if you have suggested topics, please comment.&amp;nbsp; I expect to keep pretty generic; but could get SCC-system-specific, if there&amp;#39;s interest.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fmsmvps.com%2fblogs%2fpeterritchie%2farchive%2f2009%2f03%2f11%2fdeveloping-with-source-code-control-best-practices-part-2.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fmsmvps.com%2fblogs%2fpeterritchie%2farchive%2f2009%2f03%2f11%2fdeveloping-with-source-code-control-best-practices-part-2.aspx" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1677545" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Practices/default.aspx">Software Development Practices</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Guidance/default.aspx">Software Development Guidance</category></item><item><title>A Upcoming Pandemic of Domain Anaemia</title><link>http://msmvps.com/blogs/peterritchie/archive/2009/01/29/a-upcoming-pandemic-of-domain-anaemia.aspx</link><pubDate>Thu, 29 Jan 2009 17:10:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1666992</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1666992</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2009/01/29/a-upcoming-pandemic-of-domain-anaemia.aspx#comments</comments><description>&lt;p&gt;There&amp;#39;s a well-known anti-pattern called the anaemic domain model[1][2].&amp;nbsp; This anti-pattern basically says domain entities, chronically, have little or no behaviour (remember, object-oriented design is about attributes &lt;strong&gt;and&lt;/strong&gt; behaviour).&lt;/p&gt;
&lt;p&gt;It should be obvious that a domain model that isn&amp;#39;t truly object oriented is a domain model with a problem.&amp;nbsp; But, let&amp;#39;s look at other reasons why the Anaemic Domain Model is an anti-pattern.&amp;nbsp; Your Domain is the nexus, the essence, of your system.&lt;/p&gt;
&lt;p&gt;An anaemic domain model is basically a reporting system.&amp;nbsp; Each &amp;quot;Entity&amp;quot; becomes, essentially, a query.&amp;nbsp; This is fine, reporting systems are necessary and prevalent.&amp;nbsp; But, to shoe-horn a domain model on top of this leads away from good reporting patterns that could add value and increases complexity, needlessly.&amp;nbsp; The designers spend most of their time trying to force entities on the system, without recognizing the basic reporting nature of the system.&amp;nbsp; This usually leads to &amp;quot;reports&amp;quot; that have to pull in multiple domain &amp;quot;entities&amp;quot; to generate the report--rehydringing data into an entity (usually through some sort of ORM) with no value added.&amp;nbsp; i.e. an ORM that will manage the child-parent relationship (and either pre-load or lazy-load aggregates) doesn&amp;#39;t provide much value here.&lt;/p&gt;
&lt;p&gt;The worst case scenario with an anaemic domain model is that there really is behaviour there; but it&amp;#39;s not handled in the domain entities; it&amp;#39;s handled in a different layer.&amp;nbsp; This is a problem because this circumvents the whole point of a domain model and layering.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;One indication of anaemia is that most of the domain classes&amp;nbsp; simply contain attributes.&amp;nbsp; Anyone familiar with patterns should recognize this as a Data Transfer Object, not a Domain Entity.&amp;nbsp; There&amp;#39;s nothing wrong with DTOs, they&amp;#39;re very important in almost all systems with any sort of complexity; but they&amp;#39;re not Domain Entities.&amp;nbsp; Let&amp;#39;s be truthful, there are systems with little or no behaviour in the domain; and that&amp;#39;s not a bad thing.&amp;nbsp; Systems like this likely don&amp;#39;t need a Domain Model and may not need techniques like Domain Driven Design.&amp;nbsp; The quicker people recognize that, the quicker they can be using a more appropriate architecture and design.&amp;nbsp; In some extreme cases the anaemic-domain-entity-DTOs service other DTOs&lt;/p&gt;
&lt;p&gt;Now, where am I going with this?&amp;nbsp; Well, there&amp;#39;s been a series of guidance out of Microsoft Patterns and Practice about some application &amp;quot;patterns&amp;quot;.&lt;/p&gt;
&lt;p&gt;First, let me describe what a pattern is.&amp;nbsp; A pattern is a way of &amp;quot;documenting a solution to a design problem&amp;quot; [3].&amp;nbsp; First, for it to be a pattern, it needs to detail the problem and it&amp;#39;s context, then provide a solution.&amp;nbsp; The latest &amp;quot;patterns&amp;quot; from P&amp;amp;P do not detail the problem or a context.&amp;nbsp; They&amp;#39;re simply architectural descriptions.&lt;/p&gt;
&lt;p&gt;Now the association between the Anaemic Domain Model and the latest P&amp;amp;P guidance.&amp;nbsp; In 3 of the 5 recently publish &amp;quot;patterns&amp;quot; the following is detail is included: &amp;quot;A Domain Entity pattern is used to define business entities that contain data only.&amp;quot;&amp;nbsp; This is the very definition of an Anaemic Domain Model.&amp;nbsp; Plus, in the RIA pattern the following, contradictory, detail is included: &amp;quot;Domain entities are responsible for implementing business rules.&amp;nbsp; Entities from the domain model represent business objects that contain data and implement behavior [sic]. In other words, the business objects are responsible for implementing business operations and interacting with other business objects.&amp;quot;&lt;/p&gt;
&lt;p&gt;This is disconcerting because historically sample code and guidance from Microsoft is simply reused without thought.&amp;nbsp; This leads to poorly designed and architected applications, and the .NET community as a whole is seen as one that produces poor-quality code and design.&amp;nbsp; Without context about the problems these patterns try to solve, they will be misused&amp;mdash;likely forced upon contexts and situations where they don&amp;rsquo;t fit, simply because &amp;ldquo;they&amp;rsquo;re from Microsoft&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;[1] &lt;a href="http://www.martinfowler.com/bliki/AnemicDomainModel.html" title="MF Bliki- AnemicDomainModel"&gt;MF Bliki- AnemicDomainModel&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[2] &lt;a href="http://en.wikipedia.org/wiki/Anemic_Domain_Model" title="Anemic Domain Model - Wikipedia, the free encyclopedia"&gt;Anemic Domain Model - Wikipedia, the free encyclopedia&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[3] &lt;a href="http://en.wikipedia.org/wiki/Design_pattern_(computer_science)" title="Design pattern (computer science) - Wikipedia, the free encyclopedia"&gt;Design pattern (computer science) - Wikipedia, the free encyclopedia&lt;/a&gt;&lt;/p&gt;
&lt;div style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:18e4120a-82b3-45b3-8d5c-9449fa380fad" class="wlWriterSmartContent"&gt;Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/Microsoft+Patterns+and+Practicies"&gt;Microsoft Patterns and Practicies&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/Anti-patterns"&gt;Anti-patterns&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/Anaemic"&gt;Anaemic&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/Anemic"&gt;Anemic&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/Domain+Model"&gt;Domain Model&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/Microsoft"&gt;Microsoft&lt;/a&gt;&lt;/div&gt;
&lt;div style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:bf1c39d4-6db7-4130-b9ff-995a8a4cb99f" class="wlWriterSmartContent"&gt;del.icio.us Tags: &lt;a rel="tag" href="http://del.icio.us/popular/Microsoft+Patterns+and+Practicies"&gt;Microsoft Patterns and Practicies&lt;/a&gt;,&lt;a rel="tag" href="http://del.icio.us/popular/Anti-patterns"&gt;Anti-patterns&lt;/a&gt;,&lt;a rel="tag" href="http://del.icio.us/popular/Anaemic"&gt;Anaemic&lt;/a&gt;,&lt;a rel="tag" href="http://del.icio.us/popular/Anemic"&gt;Anemic&lt;/a&gt;,&lt;a rel="tag" href="http://del.icio.us/popular/Domain+Model"&gt;Domain Model&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align:right;margin:0px;padding:4px 0px 4px 0px;" class="wlWriterHeaderFooter"&gt;&lt;a href="http://digg.com/submit?url=http%3a%2f%2fmsmvps.com%2fblogs%2fpeterritchie%2farchive%2f2009%2f01%2f29%2fa-upcoming-pandemic-of-domain-anaemia.aspx&amp;amp;title=A+Upcoming+Pandemic+of+Domain+Anaemia"&gt;&lt;img border="0" width="100" src="http://digg.com/img/badges/100x20-digg-button.png" alt="Digg This" height="20" style="border:0;" title="Digg This" /&gt;&lt;/a&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://msmvps.com/blogs/peterritchie/archive/2009/01/29/a-upcoming-pandemic-of-domain-anaemia.aspx"&gt;&lt;img border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://msmvps.com/blogs/peterritchie/archive/2009/01/29/a-upcoming-pandemic-of-domain-anaemia.aspx&amp;amp;bgcolor=0080C0&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000" alt="DotNetKick This" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1666992" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/OOD/default.aspx">OOD</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/AntiPattern/default.aspx">AntiPattern</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/DDD/default.aspx">DDD</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/ALT.NET/default.aspx">ALT.NET</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Practices/default.aspx">Software Development Practices</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Guidance/default.aspx">Software Development Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Microsoft+Patterns+and+Practices/default.aspx">Microsoft Patterns and Practices</category></item><item><title>It’s More Than Syntax</title><link>http://msmvps.com/blogs/peterritchie/archive/2009/01/29/it-s-more-than-syntax.aspx</link><pubDate>Thu, 29 Jan 2009 15:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1666425</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1666425</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2009/01/29/it-s-more-than-syntax.aspx#comments</comments><description>&lt;p&gt;Writing good software is not just about adhering to a programming language&amp;#39;s syntax.&amp;nbsp; No programming language syntax enforces good design nor does it enforce good programming in all circumstances.&lt;/p&gt;
&lt;p&gt;I&amp;#39;ve seen many systems that compiled perfectly fine; but they weren&amp;#39;t good systems.&amp;nbsp; Some exhibited reliability problems.&amp;nbsp; Some exhibited maintainability problems.&amp;nbsp; Some exhibited performance issues.&amp;nbsp; Some exhibited resistance to change.&amp;nbsp; All eventually failed at some point; either the system could not change at the required pace, or could never attain an acceptable reliability, etc.&lt;/p&gt;
&lt;p&gt;What was wrong with these systems?&amp;nbsp; The programmers didn&amp;#39;t look beyond the syntax of the language.&amp;nbsp; They didn&amp;#39;t accept that programming was about correctly constructing software, not simply writing syntactically correct code.&amp;nbsp; In almost all cases, the projects didn&amp;#39;t have design experience to guide the programming.&amp;nbsp; The lack of leadership meant that other factors like time-to-market completely dominated the quality of code written.&lt;/p&gt;
&lt;p&gt;Now, I&amp;#39;m not saying that big-design-up-front makes for better software.&amp;nbsp; Big-design-up-front may help with some of the problems of these systems; but it doesn&amp;#39;t help with others and it introduces more problems.&lt;/p&gt;
&lt;p&gt;Any good software system needs a certain amount of design, up front--you need to know what you&amp;#39;re going to be working on both from a requirements point of view and an architectural point of view.&amp;nbsp; The lowest common denominator is generally some architectural vision based upon established wisdom.&amp;nbsp; With some systems, this doesn&amp;#39;t even need to be complex.&amp;nbsp; Just enough to guide everything the programmers do.&lt;/p&gt;
&lt;p&gt;With any system, its goal is to fulfill the requirements of the stakeholders.&amp;nbsp; Some requirements (often many) are known at the onset of the project; but some are elicited throughout the evolution of the system.&amp;nbsp; I say system instead of project because a successful system generally consists of more than one project.&amp;nbsp; A project could be as granular as a particular iteration, or may be as wide as a project release.&amp;nbsp; In either case a system changes over time for as long as the system is in use.&amp;nbsp; To ignore that is to doom the system to failure.&amp;nbsp; Ignoring the fact that the system must change over the life of the system usually results in things like &amp;quot;requirements sign-off&amp;quot;, lack of iterations, big-design-up-front, etc.&lt;/p&gt;
&lt;p&gt;In any case, gauging the correctness of a system based on errors/warnings from the compiler is a mistake.&amp;nbsp; The architecture of the system must utilize established patterns for it to be maintainable and for it to be able to evolve over time.&amp;nbsp; The development of the system must employ unit testing to ensure the correctness of the system in light of its evolution.&amp;nbsp; The system must be monitored over its evolution to ensure it&amp;#39;s following the architectural design.&amp;nbsp; If it&amp;#39;s not following the architectural design, find out why; and re-evaluate the architecture if need be.&lt;/p&gt;
&lt;p&gt;In short, good programmers know much more than simply the syntax of the language they&amp;#39;re using.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:0e71f5d7-5893-44be-8c60-bfa190b88af8" class="wlWriterSmartContent"&gt;Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/software+design+architecture"&gt;software design architecture&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align:right;margin:0px;padding:4px 0px 4px 0px;" class="wlWriterHeaderFooter"&gt;&lt;a href="http://digg.com/submit?url=http%3a%2f%2fmsmvps.com%2fblogs%2fpeterritchie%2farchive%2f2009%2f01%2f29%2fit-s-more-than-syntax.aspx&amp;amp;title=It%e2%80%99s+More+Than+Syntax"&gt;&lt;img border="0" width="100" src="http://digg.com/img/badges/100x20-digg-button.png" alt="Digg This" height="20" style="border:0;" title="Digg This" /&gt;&lt;/a&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://msmvps.com/blogs/peterritchie/archive/2009/01/29/it-s-more-than-syntax.aspx"&gt;&lt;img border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://msmvps.com/blogs/peterritchie/archive/2009/01/29/it-s-more-than-syntax.aspx&amp;amp;bgcolor=0080C0&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000" alt="DotNetKick This" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1666425" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category></item><item><title>House of Cards Design Anti-pattern</title><link>http://msmvps.com/blogs/peterritchie/archive/2009/01/27/house-of-cards-design-anti-pattern.aspx</link><pubDate>Tue, 27 Jan 2009 16:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1640963</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>14</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1640963</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2009/01/27/house-of-cards-design-anti-pattern.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve had this anti-pattern in my head for years.&amp;#160; It&amp;#39;s an observance of some projects and methodologies that I&amp;#39;ve witnessed over the years.&amp;#160; I believe it&amp;#39;s a form of &lt;a href="http://en.wikipedia.org/wiki/Voodoo_programming"&gt;Voodoo Programming&lt;/a&gt;, &lt;a href="http://www.pragprog.com/the-pragmatic-programmer/extracts/coincidence"&gt;Programming by coincidence&lt;/a&gt;, and is often a side effect of &lt;a href="http://en.wikipedia.org/wiki/Cargo_cult_programming"&gt;Cargo Cult Programming&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;span style="font-size:large;"&gt;Anti-Pattern Name      &lt;br /&gt;&lt;/span&gt;House of Cards Anti-pattern&lt;/p&gt;  &lt;p&gt;&lt;span style="font-size:large;"&gt;Problem      &lt;br /&gt;&lt;/span&gt;A problem occurs when software is written that works in a specific observed scenario but no one knows why it works in that scenario.&amp;#160; Observation of &amp;quot;working&amp;quot; is taken as enough evidence of completeness.&amp;#160; It is very often not enough to observe something working in one scenario for the software to be considered &amp;quot;correct&amp;quot;.&lt;/p&gt;  &lt;p&gt;This is often a result of continual hacks in sole response to correcting bugs without consequence to design or maintainability.&amp;#160; Repeated hacks (cards) are are placed on top of other hacks until something has the appearance of &amp;quot;working&amp;quot; then all development on it stops and no one wants to go near the code again for fear of breaking it.&lt;/p&gt;  &lt;p&gt;At the very least, House of Cards design is fragile, hard to maintain, un-agile.&amp;#160; Worst case it&amp;#39;s is of low quality and prone to error and data lose.&lt;/p&gt;  &lt;p&gt;This is a general sign of &lt;a title="cowboy coding" href="http://en.wikipedia.org/wiki/Cowboy_coding"&gt;cowboy coding&lt;/a&gt;.&amp;#160; I means there is no acceptable methodology, and no real management.&amp;#160; There&amp;#39;s little development direction, and likely no development leadership (at least none with any meaningful experience).&amp;#160; Features are generally driven solely by an external source that communicates directly with developers.&lt;/p&gt;  &lt;p&gt;&lt;span style="font-size:large;"&gt;Symptoms&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;When reviewing code or questioned about code, developers respond with comments like &amp;quot;don&amp;#39;t touch it, it works&amp;quot;, or &amp;quot;we don&amp;#39;t want to change it because it works&amp;quot;.&amp;#160; There&amp;#39;s a reluctance to change the code because no one really knows &lt;em&gt;why&lt;/em&gt; it works.&amp;#160; The code stagnates, new features are slow to be implemented, and there&amp;#39;s a general un-assuredness about the code.&lt;/p&gt;  &lt;p&gt;The code is generally procedural, although following object-oriented syntax. &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div&gt;&lt;span style="font-size:large;"&gt;     &lt;p&gt;Refactored Solution&lt;/p&gt;   &lt;/span&gt;&lt;/div&gt;  &lt;p&gt;&lt;/p&gt; &lt;span style="font-size:large;"&gt;&lt;/span&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Establish experienced development leadership.&amp;#160; Establish a development methodology that separates the stakeholders from the developers.&lt;/p&gt;  &lt;p&gt;Invoke Agile methodologies to manage the requirements of the project and begin Agile redesign of the code employing unit testing, refactoring, patterns, etc.&amp;#160; Aggressively refactor the code adding unit tests to test for specific problems as they arise, until the code is robust and reliable.&amp;#160; Mandate adherence to SOLID principles: classes adhere to Single Responsibility Principle, Open-Closed Principles, Liskov Substitution Principle, Interface Segregation Principle, and uses the Dependency Inversion Principle&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:918eea6e-c712-4c23-b765-f6903cb80363" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/design" rel="tag"&gt;design&lt;/a&gt;,&lt;a href="http://technorati.com/tags/anti-pattern" rel="tag"&gt;anti-pattern&lt;/a&gt;,&lt;a href="http://technorati.com/tags/software+development" rel="tag"&gt;software development&lt;/a&gt;&lt;/div&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:right;margin:0px;padding:4px 0px 4px 0px;"&gt;&lt;a href="http://digg.com/submit?url=http%3a%2f%2fmsmvps.com%2fblogs%2fpeterritchie%2farchive%2f2009%2f01%2f27%2fhouse-of-cards-design-anti-pattern.aspx&amp;amp;title=House+of+Cards+Design+Anti-pattern"&gt;&lt;img src="http://digg.com/img/badges/100x20-digg-button.png" width="100" height="20" alt="Digg This" title="Digg This" border="0" style="border:0;" /&gt;&lt;/a&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://msmvps.com/blogs/peterritchie/archive/2009/01/27/house-of-cards-design-anti-pattern.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://msmvps.com/blogs/peterritchie/archive/2009/01/27/house-of-cards-design-anti-pattern.aspx&amp;amp;bgcolor=0080C0&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000" alt="DotNetKick This" border="0/" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1640963" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/AntiPattern/default.aspx">AntiPattern</category></item><item><title>Pass-through Constructors</title><link>http://msmvps.com/blogs/peterritchie/archive/2008/11/21/pass-through-constructors.aspx</link><pubDate>Fri, 21 Nov 2008 18:09:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1654471</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1654471</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2008/11/21/pass-through-constructors.aspx#comments</comments><description>&lt;p&gt;Pass-through constructors is a term I use to describe parameterized constructors that have none of their own logic and simply pass parameters to the base class.&amp;nbsp; For example: &lt;/p&gt;
&lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;BaseClass&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;String&lt;/span&gt; text;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; BaseClass(&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt; text)&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.text = text;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;DerivedClass&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;BaseClass&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; DerivedClass(&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt; text)&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : &lt;span style="color:#0000ff;"&gt;base&lt;/span&gt;(text)&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/p&gt;
&lt;/div&gt;
&lt;div style="text-align:left;margin:0px;padding:4px 4px 4px 4px;" class="wlWriterHeaderFooter"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://msmvps.com/blogs/peterritchie/archive/2008/11/18/pass-through-constructors.aspx&amp;amp;title=Pass-through%20Constructors"&gt;&lt;img border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://msmvps.com/blogs/peterritchie/archive/2008/11/18/pass-through-constructors.aspx&amp;amp;bgcolor=0080C0&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000" alt="DotNetKicks Image" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1654471" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Definition/default.aspx">Definition</category></item><item><title>Pontificating Virtual Parameterized Constructors in C#</title><link>http://msmvps.com/blogs/peterritchie/archive/2008/11/18/pontificating-virtual-parameterized-constructors-in-c.aspx</link><pubDate>Tue, 18 Nov 2008 17:55:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1654469</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1654469</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2008/11/18/pontificating-virtual-parameterized-constructors-in-c.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/tomholl/archive/2008/11/18/constructors-and-inheritance-why-is-this-still-so-painful.aspx"&gt;Tom Hollander recently posted&lt;/a&gt; about a change he required to the Enterprise Library for date/time validation.&amp;nbsp; He had to create a new class (rather than modify the Enterprise Library) that derived from another, defective class.&amp;nbsp; One of his complaints was that in order to effectively implement the base class he had to also write matching constructors that simply called the base class.&amp;nbsp; His suggestion was effectively to add the concept of virtual parameterized constructors to C#.&amp;nbsp; I detail &amp;ldquo;parameterized constructors&amp;rdquo; because C# already effectively has virtual default constructors.&amp;nbsp; In the following example the base constructor (Form()) is automatically called by the derivative:&lt;/p&gt;
&lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;MyForm&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;Form&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; MyForm()&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Virtual parameterized constructors are not new, and from a mere language standpoint this seems reasonable.&amp;nbsp; Pragmatically though, I believe, this is another story.&amp;nbsp; It seems logical to be able to simply inherit the parameterized constructors of the base class; but, there are so many times that this isn&amp;#39;t the case or some generally accepted principles that would be contravened by a language addition like this. &lt;/p&gt;
&lt;p&gt;Let&amp;#39;s first look at the &lt;a href="http://en.wikipedia.org/wiki/Open/closed_principle"&gt;open/closed principle&lt;/a&gt; (OCP).&amp;nbsp; The OCP suggests classes should be open for extension but closed for modification.&amp;nbsp; Robert Martin suggests [1] properly designed class hierarchies that obey OCP implement an abstraction; i.e. derive from an abstract class or implement an interface.&amp;nbsp; For example: &lt;/p&gt;
&lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;
&lt;p style="margin:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;interface&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IShape&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;{&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Draw(&lt;span style="color:#2b91af;"&gt;Graphics&lt;/span&gt; graphics);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;}&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Rectangle&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;IShape&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;{&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Draw(&lt;span style="color:#2b91af;"&gt;Graphics&lt;/span&gt; graphics)&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt;...&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;}&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Second, let&amp;#39;s look at the &amp;quot;&lt;a href="http://www.ubookcase.com/book/Addison.Wesley/CPP.Coding.Standards.101.Rules.Guidelines.and.Best.Practices/0321113586/ch34lev1sec2.html"&gt;prefer composition over inheritance&lt;/a&gt;&amp;quot; principle.&amp;nbsp; The effect of a language change like this on a design that prefers composition should be fairly obvious.&amp;nbsp; Here&amp;#39;s an example of this principle: &lt;/p&gt;
&lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;
&lt;p style="margin:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;interface&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IPolygon&lt;/span&gt; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Draw(&lt;span style="color:#2b91af;"&gt;Graphics&lt;/span&gt; graphics);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;}&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;sealed&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Polygon&lt;/span&gt; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Point&lt;/span&gt;[] points;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; Polygon(&lt;span style="color:#2b91af;"&gt;Point&lt;/span&gt;[] points) {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.points = points;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Draw(&lt;span style="color:#2b91af;"&gt;Graphics&lt;/span&gt; graphics) {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = 1; i &amp;lt; points.Length; i++) {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; graphics.DrawLine(&lt;span style="color:#2b91af;"&gt;Pens&lt;/span&gt;.Black, points[i-1], points);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;}&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Rectangle&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;IPolygon&lt;/span&gt; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Polygon&lt;/span&gt; polygon;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; Rectangle(&lt;span style="color:#2b91af;"&gt;Point&lt;/span&gt; location, &lt;span style="color:#2b91af;"&gt;Size&lt;/span&gt; size) {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Point&lt;/span&gt;[] points = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Point&lt;/span&gt;[5];&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; points[4] = points[0] = location;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; points[1] = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Point&lt;/span&gt;(location.X + size.Width, location.Y);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; points[2] = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Point&lt;/span&gt;(location.X + size.Width, location.Y + size.Height);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; points[3] = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Point&lt;/span&gt;(location.X, location.Y + size.Height);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; polygon = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Polygon&lt;/span&gt;(points);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Draw(&lt;span style="color:#2b91af;"&gt;Graphics&lt;/span&gt; graphics) {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; polygon.Draw(graphics);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;}&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Obviously there is no way to use virtual parameterized constructors here.&lt;/p&gt;
&lt;p&gt;Clearly, designs that take into account OCP and prefer-composition-over-inheritance would not benefit from a &amp;quot;virtual parameterized constructor&amp;quot; language addition. &lt;/p&gt;
&lt;p&gt;Finally, let&amp;#39;s look at why a class might have many constructors causing such friction for derivatives.&amp;nbsp; There&amp;#39;s many reasons why a class might have many constructors.&amp;nbsp; I believe all are indications of a poorly designed class.&amp;nbsp; My first thought would be that many constructors is a result of a large class and that the large-class-code-smell should be an indication for redesign.&amp;nbsp; A large class could be in an indication of a motherclass; but in either case this is likely a single responsibility principle (SRP) violation and the class is doing much more than it should and be redesigned.&amp;nbsp; If the class isn&amp;#39;t large but has many constructors, this was likely done not in response to how the class should/would be used but to cover every possible way of constructing the type.&amp;nbsp; This would then be a &lt;a href="http://en.wikipedia.org/wiki/You_Ain&amp;#39;t_Gonna_Need_It"&gt;YAGNI&lt;/a&gt; violation and the number of constructors should simply be pared down. &lt;/p&gt;
&lt;p&gt;But, what about when you have to deal with poorly design hierarchies and don&amp;#39;t have the ability to modify them?&amp;nbsp; A valid point; but, simply for the lack of friction of writing pass-through constructors I don&amp;#39;t think adding to the language to support poorly designed classes is a good for the language or its developers. &lt;/p&gt;
&lt;p&gt;While an addition like virtual parameterized constructors seems benign, its limited actual usefulness makes the effort not worth the reward.&amp;nbsp; Plus, it introduces greater abilities to create poorly designed types. &lt;/p&gt;
&lt;p&gt;[1] &lt;a href="http://www.objectmentor.com/resources/articles/ocp.pdf"&gt;http://www.objectmentor.com/resources/articles/ocp.pdf&lt;/a&gt; &lt;/p&gt;
&lt;div style="text-align:left;margin:0px;padding:4px 4px 4px 4px;" class="wlWriterHeaderFooter"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://msmvps.com/blogs/peterritchie/archive/2008/11/18/pontificating-virtual-parameterized-constructors-in-c.aspx&amp;amp;title=Pontificating%20Virtual%20Parameterized%20Constructors%20in%20C"&gt;&lt;img border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://msmvps.com/blogs/peterritchie/archive/2008/11/18/pontificating-virtual-parameterized-constructors-in-c.aspx&amp;amp;bgcolor=0080C0&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000" alt="DotNetKicks Image" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1654469" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Pontification/default.aspx">Pontification</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/OOD/default.aspx">OOD</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/AntiPattern/default.aspx">AntiPattern</category></item><item><title>Developing with Source Code Control Best Practices Part 1</title><link>http://msmvps.com/blogs/peterritchie/archive/2008/10/18/developing-with-source-code-control-best-practices-part-1.aspx</link><pubDate>Sat, 18 Oct 2008 13:54:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1651226</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1651226</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2008/10/18/developing-with-source-code-control-best-practices-part-1.aspx#comments</comments><description>&lt;p&gt;This post will detail some first principles about source code control (SCC) and provide what I consider the most basic of practices that every dev should follow.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is SCC?&lt;/strong&gt;&lt;br /&gt;SCC provides developers the ability to keep a history of their changes.&amp;nbsp; SCC allows developers the ability to group file changes together with an annotation. SCC allows developers the ability to get back to the state the project was in at any given point in time, arbitrary or specific (Beta 1, RTM, etc.).&amp;nbsp; SCC provides development teams the ability to more easily work on the same files at the same time.&amp;nbsp; SCC allows developers to see who did what, when, and usually why.&amp;nbsp; SCC allows development on more than one branch of the code at a time.&amp;nbsp; Depending on the SCC, SCC allows developers to link changes to tasks, work items, etc.&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:x-small;"&gt;&lt;strong&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-size:medium;"&gt;&lt;span style="font-size:small;"&gt;Basic practices&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;/span&gt;&lt;strong&gt;Never check in changes that cannot be built.&lt;br /&gt;&lt;/strong&gt;This is pretty self-explanatory.&amp;nbsp; Referring back to what is SCC: &amp;quot;SCC allows developers the ability to get back to the state the project was in at any given point in time&amp;quot;.&amp;nbsp; This means anyone can get back to a state where the project won&amp;#39;t build if you check in changes that cannot be built.&amp;nbsp; This causes undue friction at points temporally distant from the changes--which means there lots of work (time) involved to find and implement a solution (e.g. is the state 5 seconds before better, is the state 5 seconds after better, etc?&amp;nbsp; All things that need to be researched and tested before continuing--wasting time and resources).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Check in related changes atomically.&lt;br /&gt;&lt;/strong&gt;This builds on the first practice, if all related changes are checked in as a unit the likelihood of that check-in breaking the build is highly improbable.&amp;nbsp; Atomically means all related changes are checked in at the same time.&amp;nbsp; With most SCC systems this is extremely simple, and usually means selecting all the files you have edited (or all the subfolders you have modified folders in--or the one subfolder if you have unrelated changes, see part 2).&amp;nbsp; This might mean avoiding SCC IDE integration if your changes span several solutions. If you can&amp;#39;t check in changes atomically (really question this if you think you can&amp;#39;t.&amp;nbsp; If you honestly can&amp;#39;t, I&amp;#39;d suggest changing SCC systems) order the check ins to avoid build problems.&amp;nbsp; For example, if you added an enum to somefile.cs, then used that new enum in someotherfile.cs, check-in somefile.cs before checking-in someotherfile.cs.&amp;nbsp; Checking in somefile.cs first will not put the source code in a state where it cannot be compiled.&amp;nbsp; You&amp;#39;re working on a team, anyone on the team can get the state of the project at any time, like between non-atomic file check ins.&amp;nbsp; This means they get code that doesn&amp;#39;t compile and they won&amp;#39;t know why or how to fix it--blocking them from doing their work and wasting time and impacting the project schedule.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Make use of shelving.&lt;/strong&gt;&lt;br /&gt;If what you&amp;#39;ve coded needs to be given to someone else to get the source code to build properly, don&amp;#39;t check it in in order to give it to that other person.&amp;nbsp; On cases like this, if your SCC has shelving or shelvsets, shelve the changes and inform the other person of the shelvset instead of checking in.&amp;nbsp; Let them check in the working changes as an atomic unit.&amp;nbsp; If shelving isn&amp;rsquo;t an option (consider or petition for an SCC system that does, then), send them the files for them to check in after modifications.&amp;nbsp; See next practice.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Get all current code and build before checking in.&lt;/strong&gt;&lt;br /&gt;Someone may have made changes between when you got the code you working on and when you want to check in.&amp;nbsp; If you don&amp;#39;t get the latest code (and potentially merge it with yours), what you check-in may leave the controlled code in a state where it cannot be built.&amp;nbsp; Get all the current code to make sure you have what will be the state of the code when you check in and that it builds first.&amp;nbsp; If your build process is long, this may require several tries.&amp;nbsp; You should address build times if this is a common problem.&amp;nbsp; Communicate to the rest of the team that you need to check in changes and that they hold off on checking in related components if necessary.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fmsmvps.com%2fblogs%2fpeterritchie%2farchive%2f2008%2f10%2f18%2fdeveloping-with-source-code-control-best-practices-part-1.aspx"&gt;&lt;img border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fmsmvps.com%2fblogs%2fpeterritchie%2farchive%2f2008%2f10%2f18%2fdeveloping-with-source-code-control-best-practices-part-1.aspx" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1651226" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Practices/default.aspx">Software Development Practices</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Guidance/default.aspx">Software Development Guidance</category></item><item><title>Software Process and Reduction of Quality</title><link>http://msmvps.com/blogs/peterritchie/archive/2008/09/04/software-process-and-reduction-of-quality.aspx</link><pubDate>Thu, 04 Sep 2008 14:51:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1644079</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1644079</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2008/09/04/software-process-and-reduction-of-quality.aspx#comments</comments><description>&lt;p&gt;Ken Schwaber had a conversation with Scott Hanselman about the concept of &amp;quot;done&amp;quot;.&amp;nbsp; He said that software developers have a habit of culling down all the generally accepted practices of software development except the writing of code.&amp;nbsp; He says that, when pushed, software developers reduce quality in an effort to produce a software product by a certain time.&amp;nbsp; This leads to a huge debt that must eventually be paid.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;These generally accepted practices include things like unit testing, refactoring, design, documentation, etc.&amp;nbsp; In the case of producing an API or and SDK, I believe these practices includes community involvement.&amp;nbsp; When a team developing an SDK, API, or IDE&amp;nbsp;&amp;quot;goes dark&amp;quot;, they&amp;#39;re not doing their job properly--they&amp;#39;re ignoring the fundamental reason for their work: the customer.&amp;nbsp; This is a huge problem in our industry because software developers are effectively trained that schedules only include writing code and meetings. &lt;/p&gt;
&lt;p&gt;I agree with Ken and would say that part of an Agile process includes a significant amount of time to communicate with customers need be scheduled. &lt;/p&gt;
&lt;p&gt;Even if not professing to using an Agile methodology, if unit tests, integration tests, refactoring, and research don&amp;#39;t take up a significant amount of the software development schedule or there&amp;#39;s no scheduling of a significant amount of time to communicate with customers; the team is inept.&amp;nbsp; In this day and age, I would hazard to say its downright felonious and fraudulent.&lt;/p&gt;
&lt;div style="text-align:left;margin:0px;padding:4px 4px 4px 4px;" class="wlWriterHeaderFooter"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://msmvps.com/blogs/peterritchie/archive/2008/08/09/software-process-and-reduction-of-quality.aspx"&gt;&lt;img border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://msmvps.com/blogs/peterritchie/archive/2008/08/09/software-process-and-reduction-of-quality.aspx&amp;amp;bgcolor=0080C0&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000" alt="DotNetKicks Image" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1644079" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category></item><item><title>Becoming a Visual Studio Jedi Part 1</title><link>http://msmvps.com/blogs/peterritchie/archive/2008/09/02/becoming-a-visual-studio-jedi.aspx</link><pubDate>Tue, 02 Sep 2008 18:49:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1640948</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1640948</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2008/09/02/becoming-a-visual-studio-jedi.aspx#comments</comments><description>&lt;p&gt;&lt;span style="font-size:large;"&gt;Becoming a Visual Studio 2008 (and often Visual Studio 2005) Jedi&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In much the same grain as James&amp;#39; &lt;a href="http://www.jameskovacs.com/blog/BecomingAJediPart1OfN.aspx"&gt;Resharper Jedi&lt;/a&gt; posts, I&amp;#39;m beginning a series of posts on becoming a Visual Studio Jedi.&amp;nbsp; It involves getting the most out of Visual Studio off-the-shelf, doing things as quickly as possible and with as little friction as possible.&amp;nbsp; I think it&amp;#39;s useful for all users; but especially useful for those who are in situations where they can&amp;#39;t install refactoring tools like Refactor Pro! or Resharper.&lt;/p&gt;
&lt;p&gt;First, familiarize yourself with &lt;a href="http://blogs.msdn.com/saraford/archive/tags/Visual+Studio+2008+Tip+of+the+Day/default.aspx"&gt;Sara&amp;#39;s Visual Studio Tips&lt;/a&gt; blog; then subscribe to her blog.&lt;/p&gt;
&lt;p&gt;I&amp;#39;ll attempt to provide detail at a less granular level than Sara&amp;#39;s blog (i.e. using a series of commands to perform a specific task); but I may overlap here and there&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:large;"&gt;Take advantage of Auto-Hide &lt;br /&gt;&lt;/span&gt;Like Jimmy Bogard and Jeffery Palermo, I have my Visual Studio UI very lean. 99% of the time, I&amp;#39;m working in code.&amp;nbsp; The Solution Explorer (SE), Properties, Output, etc are auto-hide panes.&amp;nbsp; When I need to use them I hover the mouse over the tab to make them visible, do what I need to do with them, then get back to the code.&amp;nbsp; The Code Editor is the only window that isn&amp;#39;t auto-hide or floating. &lt;br /&gt;&lt;img src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/peterritchie/lean-VS2k8.JPG" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:large;"&gt;Navigate find results via keyboard&lt;/span&gt; &lt;br /&gt;Whenever anything is displayed in a find results window, you can iterate each item in the list via a keystroke.&amp;nbsp; The default C# keyboard map had F8 and Shift+F8 as the shortcuts for next and previous.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Press Ctrl+Shift+F to bring up the Find in Files form. &lt;/li&gt;
&lt;li&gt;Enter &amp;quot;TODO\:.*refactor&amp;quot; in the &amp;quot;Find what&amp;quot; text box. &lt;/li&gt;
&lt;li&gt;Ensure Match case, Match whole word are unchecked. &lt;/li&gt;
&lt;li&gt;Ensure Use is checked and has Regular expressions selected. &lt;/li&gt;
&lt;li&gt;Press Alt+F to search. &lt;br /&gt;&lt;img src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/peterritchie/Find-in-Files.JPG" alt="" /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A Find Results window is displayed that shows the results of the search. &lt;br /&gt;&lt;img src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/peterritchie/Find-Results.JPG" alt="" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;F8&lt;/strong&gt; goes to the first result.&lt;/li&gt;
&lt;li&gt;Pressing &lt;strong&gt;F8&lt;/strong&gt; again goes to the next. &lt;/li&gt;
&lt;li&gt;Pressing &lt;strong&gt;Shift+F8&lt;/strong&gt; goes to the previous result.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See also: &lt;br /&gt;&lt;a href="http://blogs.msdn.com/saraford/archive/2008/04/18/did-you-know-you-can-use-f8-and-shift-f8-to-navigate-among-errors-in-the-output-window.aspx"&gt;http://blogs.msdn.com/saraford/archive/2008/04/18/did-you-know-you-can-use-f8-and-shift-f8-to-navigate-among-errors-in-the-output-window.aspx&lt;/a&gt; &lt;br /&gt;&lt;a href="http://blogs.msdn.com/saraford/archive/2007/11/08/did-you-know-how-to-use-f8-to-navigate-the-find-results-window.aspx"&gt;http://blogs.msdn.com/saraford/archive/2007/11/08/did-you-know-how-to-use-f8-to-navigate-the-find-results-window.aspx&lt;/a&gt; &lt;br /&gt;&lt;a href="http://blogs.msdn.com/saraford/archive/2005/03/30/403887.aspx"&gt;http://blogs.msdn.com/saraford/archive/2005/03/30/403887.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;F8 and Shift+F8 work for most lists like Find Results 1, Find Results 2, Error List, Output:Build, etc.&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:large;"&gt;File name extensions when adding classes&lt;/span&gt; &lt;br /&gt;Do you find your self selecting text in the file name when you use the Add Class wizard?&amp;nbsp; Or, do you always type &amp;quot;.cs&amp;quot; at the end of your file name?&amp;nbsp; You may be happy to know you don&amp;#39;t have to do that.&amp;nbsp; Simply invoke the Add Class wizard and type the name of the class.&amp;nbsp; The wizard adds the missing .cs for you.&amp;nbsp; For example: &lt;br /&gt;Press Alt+P, C &lt;br /&gt;Enter &amp;quot;MyNewClass&amp;quot; &lt;br /&gt;Press Enter &lt;br /&gt;A file MyNewClass.cs is added to your project and it contains class named &amp;quot;MyNewClass&amp;quot;.&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:large;"&gt;Consider a Custom toolbar&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;There&amp;#39;s generally only handful of toolbar buttons that you might need, especially if you&amp;#39;re a keyboard user like me.&amp;nbsp; There&amp;#39;s some things that simply don&amp;#39;t have a default keyboard mapping.&amp;nbsp; Another good reason for having a custom toolbar item with only the buttons you use is if you often change the size of your Visual Studio window.&amp;nbsp; The default layout has two or more toolbars (depending on the edition and any add-ins you have installed).&amp;nbsp; You can carefully position those toolbars so they may take up one or two lines; but when you then shrink the size of your window the get wrapped and they won&amp;#39;t restore if you expand the size of your window.&amp;nbsp; Having a single toolbar means this wrapping of toolbars can never happen.&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:large;"&gt;Export Settings&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Once you get your UI the way you want it, you can actually save the layout.&amp;nbsp; &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Click on Tools\Import and Export Settings.&lt;/li&gt;
&lt;li&gt;Select Export selected environment settings.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is really handy if you get into low-resource situations (like the application you&amp;#39;re developing or its framework uses up too many GDI handles and Visual Studio can&amp;#39;t allocate a handle to display a toolbar or a frame.&amp;nbsp; When this happens Visual Studio actually turns off those GUI elements; when you close and restart those panes/frames are no longer displayed by default.)&lt;/p&gt;
&lt;div style="text-align:left;margin:0px;padding:4px 4px 4px 4px;" class="wlWriterHeaderFooter"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://msmvps.com/blogs/peterritchie/archive/2008/07/15/becoming-a-visual-studio-jedi.aspx&amp;amp;title=Becoming%20a%20Visual%20Studio%20Jedi%20Part%201"&gt;&lt;img border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://msmvps.com/blogs/peterritchie/archive/2008/07/15/becoming-a-visual-studio-jedi.aspx&amp;amp;bgcolor=0080C0&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000" alt="DotNetKicks Image" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1640948" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/DevCenterPost/default.aspx">DevCenterPost</category></item><item><title>Trials and Tribulations of DataGridView, Column Selections, and Sorting</title><link>http://msmvps.com/blogs/peterritchie/archive/2008/08/26/trials-and-tribulations-of-datagridview-column-selections-and-sorting.aspx</link><pubDate>Tue, 26 Aug 2008 20:06:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1645891</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1645891</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2008/08/26/trials-and-tribulations-of-datagridview-column-selections-and-sorting.aspx#comments</comments><description>&lt;p&gt;I had to implement some &lt;em&gt;custom&lt;/em&gt; sorting in a &lt;span style="font-family:Courier New;"&gt;DataGridView&lt;/span&gt; recently.&amp;nbsp; Essentially, the stakeholders wanted full column selection (like Excel) while still having the ability to sort the data based on a particular column.&lt;/p&gt;
&lt;p&gt;This particular &lt;span style="font-family:Courier New;"&gt;DataGridView&lt;/span&gt; is data-bound.&amp;nbsp; &lt;span style="font-family:Courier New;"&gt;DataGridView&lt;/span&gt; offers the &lt;span style="font-family:courier new,courier;"&gt;Sort(DataGridViewColumn, ListSortDirection)&lt;/span&gt; method to perform this.&amp;nbsp; Nice and easy I thought: I&amp;rsquo;ll set the &lt;span style="font-family:Courier New;"&gt;SelectionMode&lt;/span&gt; to &lt;span style="font-family:Courier New;"&gt;DataGridViewSelectionMode.ColumnHeaderSelect&lt;/span&gt; and simply call &lt;span style="font-family:courier new,courier;"&gt;Sort&lt;/span&gt; with the selected column.&lt;/p&gt;
&lt;p&gt;Well, much to my chagrin this had the side effect of making that column look selected all the time.&amp;nbsp; No matter where else I clicked, that recently sorted column &lt;em&gt;looked&lt;/em&gt; selected (&lt;span style="font-family:Courier New;"&gt;SelectedColumns&lt;/span&gt; had a count of zero).&amp;nbsp; And to add insult to injury, when I control-clicked that column (thinking it was selected) to unselected it, it caused a &lt;span style="font-family:Courier New;"&gt;NullReferenceException&lt;/span&gt; deep in the framework.&lt;/p&gt;
&lt;p&gt;Suffice it to say, this makes it very difficult to sort by columns in &lt;span style="font-family:Courier New;"&gt;DataGridView&lt;/span&gt; without using the built-in sort-column-when-header-is-clicked mode.&lt;/p&gt;
&lt;p&gt;What I&amp;rsquo;m now attempting to do is to unselect the column before sorting it.&amp;nbsp; &lt;span style="text-decoration:line-through;"&gt;This, in itself, is not trivial either; there&amp;rsquo;s no public method to select or deselect a column in the &lt;span style="font-family:Courier New;"&gt;DataGridView&lt;/span&gt;.&amp;nbsp; I&amp;rsquo;ve had to create a new &lt;span style="font-family:Courier New;"&gt;DataGridView&lt;/span&gt; derivative and call the protected method &lt;span style="font-family:Courier New;"&gt;SetSelectedColumnCore&lt;/span&gt;.&amp;nbsp; A few hoops&amp;hellip;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve logged a couple of issues on Microsoft Connect about these problems.&amp;nbsp; The first is about ctrl-clicking the column and getting an exception:&amp;nbsp; &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=363623" title="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=363623"&gt;https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=363623&lt;/a&gt; The second is about the visual state of the column remaining &amp;ldquo;selected&amp;rdquo;: &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=363623"&gt;https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=363623&lt;/a&gt; Attached to this post you will find the project referenced by the two Connect issues.&lt;/p&gt;
&lt;p&gt;[Update: I&amp;#39;ve currently only tried this with a .NET 2.0 project in Visual Studio 2008 SP1; if you find this problem occurs in Visual 2008 RTM, please comment.]&lt;/p&gt;
&lt;p&gt;[Update: I overlooked the DataGridViewColumn.Select property, so there&amp;#39;s no need to derive from &lt;span style="font-family:courier new,courier;"&gt;DataGridView&lt;/span&gt;]&lt;/p&gt;
&lt;div style="text-align:left;margin:0px;padding:4px 4px 4px 4px;" class="wlWriterHeaderFooter"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://msmvps.com/blogs/peterritchie/archive/2008/08/26/trials-and-tribulations-of-datagridview-column-selections-and-sorting.aspx&amp;amp;title=Trials%20and%20Tribulations%20of%20DataGridView,%20Column%20Selections,%20and%20Sorting"&gt;&lt;img border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://msmvps.com/blogs/peterritchie/archive/2008/08/26/trials-and-tribulations-of-datagridview-column-selections-and-sorting.aspx&amp;amp;bgcolor=0080C0&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000" alt="DotNetKicks Image" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1645891" width="1" height="1"&gt;</description><enclosure url="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.01.64.58.91/DataGridViewBug.zip" length="22598" type="application/x-zip-compressed" /><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Framework+Bugs/default.aspx">Framework Bugs</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Connect+Issue/default.aspx">Connect Issue</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Visual+Studio+2008+SP1/default.aspx">Visual Studio 2008 SP1</category></item><item><title>The winds of change are blowing</title><link>http://msmvps.com/blogs/peterritchie/archive/2008/08/20/the-winds-of-change-are-blowing.aspx</link><pubDate>Wed, 20 Aug 2008 15:14:26 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1645211</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1645211</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2008/08/20/the-winds-of-change-are-blowing.aspx#comments</comments><description>&lt;p&gt;The essence of ALT.NET, or at least the essence that people made use of, was that it was a venue for improving one&amp;#39;s skills.&amp;#160; There has always been an undercurrent of other agendas there; but they never really took root. &lt;/p&gt;  &lt;p&gt;The problem with the ALT.NET moniker was it isolates it from most of the industry--it was an island of .NET practitioners.&amp;#160; This basically flicked its thumb at the other communities--other communities that propagated some of the guidance that ALT.NET was trying to proliferate. &lt;/p&gt;  &lt;p&gt;In the very spirit of continuous improvement it seems that ALT.NET is attempting to evolve and the ALT.NET conferences may continue (at least for a period of time, until the next kaikaku) as Kaizen conference. &lt;/p&gt;  &lt;p&gt;Kaizen is a much more appropriate name for what people use and get out of the ALT.NET conferences.&amp;#160; I just hope this change doesn&amp;#39;t cause division, distrust and dissent (for lack of a better word). &lt;/p&gt;  &lt;p&gt;I&amp;#39;ve said from the beginning that &amp;quot;ALT.NET&amp;quot; had some flaws as a name.&amp;#160; I hope Kaizen will continue to give the same people the ability to improve, while embracing more.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:left;margin:0px;padding:4px 4px 4px 4px;"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://msmvps.com/blogs/peterritchie/archive/2008/08/20/the-winds-of-change-are-blowing.aspx&amp;amp;title=The%20winds%20of%20change%20are%20blowing"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://msmvps.com/blogs/peterritchie/archive/2008/08/20/the-winds-of-change-are-blowing.aspx&amp;amp;bgcolor=0080C0&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000" alt="DotNetKicks Image" border="0/" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1645211" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/ALT.NET/default.aspx">ALT.NET</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Kaikaku/default.aspx">Kaikaku</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Kaizen/default.aspx">Kaizen</category></item><item><title>Extra Features: One of the Lean 7 Wastes of Software</title><link>http://msmvps.com/blogs/peterritchie/archive/2008/08/18/extra-features-one-of-the-lean-7-wastes-of-software.aspx</link><pubDate>Mon, 18 Aug 2008 15:11:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1644246</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1644246</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2008/08/18/extra-features-one-of-the-lean-7-wastes-of-software.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://devlicio.us/blogs/derik_whittaker/default.aspx"&gt;Derik Whittaker&lt;/a&gt; recently &lt;a href="http://devlicio.us/blogs/derik_whittaker/archive/2008/08/06/unused-code-is-the-worst-of-the-7-wastes-of-software.aspx"&gt;blogged about how writing unused code is one of the Lean 7 Wastes of Software&lt;/a&gt;.&amp;nbsp; Mary Poppendieck calls this &amp;quot;Extra Features&amp;quot; and has a one-to-one association to overproduction in manufacturing.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;In Manufacturing it has different caveats: if you overproduce something you have to have somewhere to store it until its sold.&amp;nbsp; What do you do when you don&amp;#39;t have the space to store it?&amp;nbsp; If you have the space, it&amp;#39;s not too much of an issue; you just tuck it away; but you still need people to move it, manage the space, manage the responsibilities around moving/storage, etc. etc. &lt;/p&gt;
&lt;p&gt;With Lean Software, there is still technically a storage issue (VCS, disk space, etc.).&amp;nbsp; The real issue with extra features is that no one is using them. In the best case this means you&amp;#39;re consuming expensive resources that aren&amp;#39;t directly increasing revenue.&amp;nbsp; Worst case you&amp;#39;re also impacting the usability (and thus the sell-ability) of the software.&amp;nbsp; If the extra features are something that the vendor hopes to be used in the future; then you&amp;#39;ve increased the time between implementation and fixing bugs.&amp;nbsp; Unit testing aside, when customers log bugs against the software regarding something implement 6 months ago, you&amp;#39;ve increased the cost of fixing the bug exponentially as time goes on.&amp;nbsp; This is the philosophy behind TDD, that unit tests find bugs as soon as possible (~build time, depending you your setup). &lt;/p&gt;
&lt;p&gt;From an Agile standpoint, extra features mean you&amp;#39;re giving the user something they didn&amp;#39;t want.&amp;nbsp; This means you&amp;#39;re not listening to your customer and don&amp;#39;t have a relationship built on communication.&amp;nbsp; In Agile, it&amp;#39;s a tenet to build prototype code based ideas you&amp;#39;ve inferred from communication with the customer.&amp;nbsp; This isn&amp;#39;t extra features, this is the feedback process.&amp;nbsp; It&amp;#39;s fine to propose a feature to the user in the form of a prototype; but if they don&amp;#39;t want it, it doesn&amp;#39;t go into the release. &lt;/p&gt;
&lt;p&gt;Extra features is technical debt that you&amp;#39;ll have to pay for eventually.&lt;/p&gt;
&lt;div style="text-align:left;margin:0px;padding:4px 4px 4px 4px;" class="wlWriterHeaderFooter"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://msmvps.com/blogs/peterritchie/archive/2008/08/11/extra-features-one-of-the-lean-7-wastes-of-software.aspx&amp;amp;title=Extra%20Features:%20one%20of%20the%20Lean%207%20Wastes%20of%20Software"&gt;&lt;img border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://msmvps.com/blogs/peterritchie/archive/2008/08/11/extra-features-one-of-the-lean-7-wastes-of-software.aspx&amp;amp;bgcolor=0080C0&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000" alt="DotNetKicks Image" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1644246" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Lean/default.aspx">Lean</category></item><item><title>Law of Reversibility of Attributes</title><link>http://msmvps.com/blogs/peterritchie/archive/2008/08/13/law-of-reversibility-of-attributes.aspx</link><pubDate>Wed, 13 Aug 2008 21:55:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1643832</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1643832</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2008/08/13/law-of-reversibility-of-attributes.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve&amp;nbsp;come up with a simple law called Law of Reversability of Attributes.&amp;nbsp; It&amp;rsquo;s based on the physics law of a similar name.&amp;nbsp; Basically what the law means is that the inverse of a transformation should result in a return to the original state.&lt;/p&gt;
&lt;p&gt;The Law of Reversibility of Attributes is defined as:&lt;/p&gt;
&lt;p&gt;For a given state of an object; when a attribute&amp;rsquo;s value is changed, the inverse of that value, when applied to that attribute, will result in the object returning to its original state.&lt;/p&gt;
&lt;p&gt;I say &amp;ldquo;attribute&amp;rdquo; rather than &amp;ldquo;property&amp;rdquo; to encompass methods that imply setting of attributes.&amp;nbsp; So, for example&lt;/p&gt;
&lt;div style="border-right:black 1px solid;border-top:black 1px solid;font-size:10pt;background:white;border-left:black 1px solid;color:black;border-bottom:black 1px solid;font-family:courier new;"&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; myObject.BooleanValue = !myObject.BooleanValue;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; myObject.BooleanValue = !myObject.BooleanValue;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;div style="border-right:black 1px solid;border-top:black 1px solid;font-size:10pt;background:white;border-left:black 1px solid;color:black;border-bottom:black 1px solid;font-family:courier new;"&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; myObject.SetBooleanValue(!myObject.GetBooleanValue());&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; myObject.SetBooleanValue(!myObject.BooleanValue());&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;means &lt;em&gt;myObject&lt;/em&gt; will be in the same state after the second line of code than it was before the first line of code.&lt;/p&gt;
&lt;p&gt;[UPDATE: interestingly, after I wrote this post--which was delay-published--&lt;a href="http://srtsolutions.com/blogs/billwagner/default.aspx"&gt;Bill Wagner&lt;/a&gt; wrote a great &lt;a href="http://visualstudiomagazine.com/columns/article.aspx?editorialsid=2719"&gt;article on a very similar topic&lt;/a&gt; in Visual Studio Magazine]&lt;/p&gt;
&lt;div style="text-align:left;margin:0px;padding:4px 4px 4px 4px;" class="wlWriterHeaderFooter"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://msmvps.com/blogs/peterritchie/archive/2008/08/07/law-of-reversibility-of-attributes.aspx&amp;amp;title=Law%20of%20Reversibility%20of%20Attributes"&gt;&lt;img border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://msmvps.com/blogs/peterritchie/archive/2008/08/07/law-of-reversibility-of-attributes.aspx&amp;amp;bgcolor=0080C0&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000" alt="DotNetKicks Image" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1643832" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category></item><item><title>DataGridViewColumn.Frozen</title><link>http://msmvps.com/blogs/peterritchie/archive/2008/08/11/datagridviewcolumn-frozen.aspx</link><pubDate>Mon, 11 Aug 2008 22:34:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1640969</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1640969</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2008/08/11/datagridviewcolumn-frozen.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridviewcolumn.frozen(VS.80).aspx"&gt;DataGridViewColumn.Frozen&lt;/a&gt; is documented as &amp;quot;When a column is frozen, all the columns to its left (or to its right in right-to-left languages) are frozen as well.&amp;quot;&lt;/p&gt; &lt;p&gt;Which is nice until you think of the consequences.&amp;nbsp; The consequences being that freezing a column and all columns to the left is performed with a single assignment of true to the Frozen property of that column; but to unfreeze is not the opposite (a assignment of false to the Frozen property of that column).&amp;nbsp; No, you must unfreeze each of those columns to the left.&amp;nbsp; This can be done by manually unfreezing each column, or by unfreezing column 0.&lt;/p&gt; &lt;p&gt;This means that column.Frozen = false is not the opposite of column.Frozen = true—resulting in unbalanced reversible side-effects.&lt;/p&gt; &lt;p&gt;Neither of the techniques to “unfreeze” the column that was frozen is intuitive; but unfortunately this interface is not &amp;quot;intention revealing&amp;quot;.&amp;nbsp; You’re not just setting the Frozen property of a column, you’re setting the frozen property of that column and all the columns to the left.&lt;/p&gt; &lt;p&gt;Greg Young recently commented (I don’t remember where) about writing classes without &lt;em&gt;any&lt;/em&gt; properties.&amp;nbsp; This approach would have helped here.&amp;nbsp; What Greg is alluding to is to recognize behaviour rather than shape.&amp;nbsp; Freezing the current column and all columns to the left is a behaviour, not an attribute; and it should be modeled as a method rather than a property.&lt;/p&gt; &lt;p&gt;At any rate, if you have a DataGridView on your form, you may be interested in using these methods instead:&lt;/p&gt; &lt;div style="border-right:black 1px solid;border-top:black 1px solid;font-size:10pt;background:white;border-left:black 1px solid;color:black;border-bottom:black 1px solid;font-family:courier new;"&gt;&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; FreezeAtColumn(&lt;span style="color:blue;"&gt;int&lt;/span&gt; value)&lt;/pre&gt;&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dataGridView.Columns[value].Frozen = &lt;span style="color:blue;"&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; UnfreezeColumns()&lt;/pre&gt;&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dataGridView.Columns[0].Frozen = &lt;span style="color:blue;"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;/div&gt;&lt;pre&gt;&lt;/pre&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:left;margin:0px;padding:4px 4px 4px 4px;"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://msmvps.com/blogs/peterritchie/archive/2008/07/15/datagridviewcolumn-frozen.aspx&amp;amp;title=DataGridViewColumn.Frozen"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://msmvps.com/blogs/peterritchie/archive/2008/07/15/datagridviewcolumn-frozen.aspx&amp;amp;bgcolor=0080C0&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000" alt="DotNetKicks Image" border="0/" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1640969" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category></item><item><title>ITSWITCH #1: Answer</title><link>http://msmvps.com/blogs/peterritchie/archive/2008/07/28/itswitch-1-answer.aspx</link><pubDate>Mon, 28 Jul 2008 19:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1642162</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1642162</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2008/07/28/itswitch-1-answer.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/peterritchie/archive/2008/07/25/itswitch-1.aspx"&gt;Last post&lt;/a&gt; I detailed some code that may or may not have something wrong in it.&amp;#160; If you thought InitializeOne and IntializeTwo are semantically identical (e.g. they differ only by performance), you&amp;#39;d be wrong.&lt;/p&gt;  &lt;p&gt;If you simply ran the code, you&amp;#39;d be able to guess where the problem is.&amp;#160; To understand what&amp;#39;s causing the problem.&amp;#160; Let&amp;#39;s look at how C# effectively implements the two loops.&lt;/p&gt;  &lt;p&gt;InitializeOne is essentially equivalent to&lt;/p&gt;  &lt;div style="border-right:black 1px solid;border-top:black 1px solid;font-size:10pt;background:white;border-left:black 1px solid;color:black;border-bottom:black 1px solid;font-family:courier new;"&gt;   &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;PrivateDelegateHelper&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;String&lt;/span&gt; Value { &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;; }&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Method()&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;TestClass&lt;/span&gt;.ProcessText(Value);&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; InitializeThree(&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;[] strings)&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; delegates = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;MethodInvoker&lt;/span&gt;&amp;gt;(strings.Length);&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;MethodInvoker&lt;/span&gt; cachedAnonymousDelegate = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;PrivateDelegateHelper&lt;/span&gt; privateDelegateHelper = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;PrivateDelegateHelper&lt;/span&gt;();&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;[] copyOfStrings = strings;&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; copyOfStrings.Length; ++i)&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; privateDelegateHelper.Value = copyOfStrings;&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (cachedAnonymousDelegate == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cachedAnonymousDelegate = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;MethodInvoker&lt;/span&gt;(privateDelegateHelper.Method);&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; delegates.Add(cachedAnonymousDelegate);&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now it&amp;#39;s obvious, right?&lt;/p&gt;

&lt;p&gt;For those you don&amp;#39;t want to read all the code, the problem is that only one PrivateDelegateHelper object is instantiated and its value property is set in each iteration of the loop.&amp;#160; Because the delegates aren&amp;#39;t run until sometime after the loop, they&amp;#39;re all run with the last value of the string array as their argument.&lt;/p&gt;

&lt;p&gt;The technical term for what we&amp;#39;ve implemented here is a &lt;a href="http://en.wikipedia.org/wiki/Closure_(computer_science)"&gt;closure&lt;/a&gt;.&amp;#160; If you&amp;#39;re using Resharper 4.x, you would have noticed a warning &amp;quot;Access to modified closure&amp;quot;:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;img height="132" src="http://msmvps.com/cfs-filesystemfile.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/peterritchie/modified-closure.JPG" width="564" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;...which is attempting to tell you that the closure (the delegate and cached bound variables) has changed (in this case one of the bound variables has changed between the creation of a closure and another and out expected output is effected).&lt;/p&gt;

&lt;p&gt;By the way, you can get the same thing with C# 3+ with lambdas (i.e. you can also write closures with lambdas):&lt;/p&gt;

&lt;div style="border-right:black 1px solid;border-top:black 1px solid;font-size:10pt;background:white;border-left:black 1px solid;color:black;border-bottom:black 1px solid;font-family:courier new;"&gt;
  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; InitializeOne(&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;[] strings)&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; delegates = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;MethodInvoker&lt;/span&gt;&amp;gt;(strings.Length);&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;for&lt;/span&gt; (&lt;span style="color:blue;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; strings.Length; ++i)&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;String&lt;/span&gt; value = strings;&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; delegates.Add(() =&amp;gt; ProcessText(value));&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; InitializeTwo(&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;[] strings)&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; delegates = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;MethodInvoker&lt;/span&gt;&amp;gt;(strings.Length);&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt; value &lt;span style="color:blue;"&gt;in&lt;/span&gt; strings)&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; delegates.Add(() =&amp;gt; ProcessText(value));&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="wlWriterHeaderFooter" style="text-align:left;margin:0px;padding:4px 4px 4px 4px;"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://msmvps.com/blogs/peterritchie/archive/2008/07/28/itswitch-1-answer.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://msmvps.com/blogs/peterritchie/archive/2008/07/28/itswitch-1-answer.aspx&amp;amp;bgcolor=0080C0&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000" border="0/" alt="" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1642162" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+2.0/default.aspx">.NET 2.0</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Pop+Quiz/default.aspx">Pop Quiz</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/ITSWITCH+Answer/default.aspx">ITSWITCH Answer</category></item><item><title>ITSWITCH: #1</title><link>http://msmvps.com/blogs/peterritchie/archive/2008/07/25/itswitch-1.aspx</link><pubDate>Fri, 25 Jul 2008 18:58:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1642154</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1642154</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2008/07/25/itswitch-1.aspx#comments</comments><description>&lt;p&gt;Is There Something Wrong In This Code Here&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#ff0000;"&gt;UPDATE: as several readers pointed out there was compile error in the code what was being displayed.&amp;nbsp; The line &amp;quot;String value = string&amp;quot; was showing up as &amp;quot;String value = string&amp;quot;.&amp;nbsp; I&amp;#39;m not sure why; but throwing some spaces between the i and the square brackets seems to have solved it.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In the following class, is there something wrong with either InitializeOne or InitializeTwo (hint, it has nothing to do with compile errors and I&amp;#39;m ignoring&amp;nbsp;performance differences)?&lt;/p&gt;
&lt;div style="font-size:10pt;background:white;color:black;font-family:Courier New;border:black 1px solid;"&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;TestClass&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;MethodInvoker&lt;/span&gt;&amp;gt; delegates;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; ProcessText(&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt; text)&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Trace&lt;/span&gt;.WriteLine(text);&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Run()&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;MethodInvoker&lt;/span&gt; invoker &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; delegates)&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; invoker();&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; InitializeOne(&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;[] strings)&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; delegates = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;MethodInvoker&lt;/span&gt;&amp;gt;(strings.Length);&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; strings.Length; ++i)&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;String&lt;/span&gt; value = strings[ i ];&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; delegates.Add(&lt;span style="color:#0000ff;"&gt;delegate&lt;/span&gt; { ProcessText(value); });&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; InitializeTwo(&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;[] strings)&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; delegates = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;MethodInvoker&lt;/span&gt;&amp;gt;(strings.Length);&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt; value &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; strings)&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; delegates.Add(&lt;span style="color:#0000ff;"&gt;delegate&lt;/span&gt; { ProcessText(value); });&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Answer on Monday.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1642154" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+2.0/default.aspx">.NET 2.0</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Pop+Quiz/default.aspx">Pop Quiz</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/ITSWITCH/default.aspx">ITSWITCH</category></item><item><title>Working with Resharper's External Annotation XML Files</title><link>http://msmvps.com/blogs/peterritchie/archive/2008/07/21/working-with-resharper-s-external-annotation-xml-files.aspx</link><pubDate>Mon, 21 Jul 2008 20:32:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1640964</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1640964</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2008/07/21/working-with-resharper-s-external-annotation-xml-files.aspx#comments</comments><description>&lt;p&gt;Resharper 4.0 has external annotation XML files that you can create to give Resharper more information about your code.&amp;nbsp; For example, you can tell Resharper that a particular method does not accept a null argument.&amp;nbsp; For example, the following method does not accept a null argument:&lt;/p&gt;
&lt;div style="font-size:10pt;background:white;color:black;font-family:Courier New;border:black 1px solid;"&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; System;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&lt;span style="color:blue;"&gt;namespace&lt;/span&gt; Utility&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;{&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Text&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;int&lt;/span&gt; GetLength(&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt; text)&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (text == &lt;span style="color:blue;"&gt;null&lt;/span&gt;) &lt;span style="color:blue;"&gt;throw&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;text&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; text.Length;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;An external annotation file can be created to inform Resharper of this fact and have it warn you when possible null values are passed as an argument:&lt;/p&gt;
&lt;div style="font-size:10pt;background:white;color:black;font-family:Courier New;border:black 1px solid;"&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;String&lt;/span&gt; text = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Utility.Text.GetLength(text);&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;First, you need to create a directory within the Resharper ExternalAnnotations directory.&amp;nbsp; This ExternalAnnotations directory is usually in the form of &amp;quot;%SystemDrive%\Program Files\JetBrains\ReSharper\vBuild#\Bin\ExternalAnnotations&amp;quot; for example &amp;quot;C:\Program Files\JetBrains\ReSharper\v4.0.816.4\Bin\ExternalAnnotations&amp;quot;.&lt;/p&gt;
&lt;p&gt;The directory we need to create is the same name as our assembly (without the extension).&amp;nbsp; In our case this would be &amp;quot;C:\Program Files\JetBrains\ReSharper\v4.0.816.4\Bin\ExternalAnnotations\Utility&amp;quot;.&lt;/p&gt;
&lt;p&gt;Next, we need to create an XML file to contain the information required by Resharper.&amp;nbsp; The name of this file is the same as the directory name, plus &amp;quot;.xml&amp;quot;.&amp;nbsp; So, the full file name would be &amp;quot;C:\Program Files\JetBrains\ReSharper\v4.0.816.4\Bin\ExternalAnnotations\Utility\Utility.xml&amp;quot;.&amp;nbsp; This file essentially has an assembly element with child member elements that provide meta-data about methods and arguments.&amp;nbsp; In our case we want to tell Resharper that the Utility.Text.GetLength(String) method does not accept null values for the argument named &amp;quot;text&amp;quot;.&amp;nbsp; To do this we populate the file with the following XML:&lt;/p&gt;
&lt;div style="font-size:10pt;background:white;color:black;font-family:Courier New;border:black 1px solid;"&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color:#a31515;"&gt;xml&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;version&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;1.0&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;encoding&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;utf-8&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; ?&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;assembly&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;Utility&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;member&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;M:Utility.Text.GetLength(System.String)&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;parameter&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;text&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;attribute&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;ctor&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;M:JetBrains.Annotations.NotNullAttribute.#ctor&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;parameter&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;member&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;assembly&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;After restarting Visual Studio, Resharper will now warn that &amp;quot;text&amp;quot;, when passed to GetLength, in the following code, has a &amp;quot;Possible &amp;#39;null&amp;#39; assignment to entity marked with &amp;quot;NotNull&amp;quot; attribute&amp;quot;.&lt;/p&gt;
&lt;div style="font-size:10pt;background:white;color:black;font-family:Courier New;border:black 1px solid;"&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;String&lt;/span&gt; text = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Utility.Text.GetLength(text);&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I&amp;#39;ve tried this with the GA build and with both Visual Studio 2005 (SP1) and Visual Studio 2008.&lt;/p&gt;
&lt;p&gt;For more information about the annotation options, search for AssertionConditionType in the Resharper help and browse around &amp;quot;%SystemDrive%\Program Files\JetBrains\ReSharper\vBuild#\Bin\ExternalAnnotations&amp;quot; for examples.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1640964" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Resharper/default.aspx">Resharper</category></item><item><title>Drag-copying in Visual Studio Solution Explorer.</title><link>http://msmvps.com/blogs/peterritchie/archive/2008/07/18/drag-copying-in-visual-studio-solution-explorer.aspx</link><pubDate>Fri, 18 Jul 2008 16:46:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1640926</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1640926</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2008/07/18/drag-copying-in-visual-studio-solution-explorer.aspx#comments</comments><description>&lt;p&gt;NOTE: I&amp;#39;ve tried this in Visual Studio 2008 (VS2k8), I&amp;#39;m assuming the same thing happens in Visual Studio 2005 (VS2k5).&lt;/p&gt;
&lt;p&gt;In the process of refactoring, it&amp;#39;s *very* common for me to rename a type.&amp;nbsp; This is most easily done by renaming the file in the Solution Explorer (SE)--which renames the file, the type, and and any uses of the type in the entire solution.&lt;/p&gt;
&lt;p&gt;Occasionally, I need to create a new type based on another.&amp;nbsp; Copying an abstract type in order to implement the abstract type is often handy--I just fill in the abstract members (and delete &amp;quot;abstract&amp;quot;) in the copied type after renaming it.&lt;/p&gt;
&lt;p&gt;Drag-copy in the SE seems like it would take care of a couple of steps at once for me: make a copy and rename it.&amp;nbsp; Unfortunately it doesn&amp;#39;t do that.&amp;nbsp; It makes a copy of the file (as &amp;quot;Copy of typename.xx&amp;quot;) but doesn&amp;#39;t rename any types in the class that match the file name.&lt;/p&gt;
&lt;p&gt;This might seem somewhat trivial... I can simply rename the file name then refactor rename the type in the file so that the type and all it&amp;#39;s constructors are renamed in one fell swoop.&amp;nbsp; Alas, this simply opens a can of worms that can completely confound a newcomer and annoy an expert.&lt;/p&gt;
&lt;p&gt;That simple, intuitive method of renaming a copy of a file then the type within the file actually renames *all* types of that name.&amp;nbsp; Since we&amp;#39;ve just made a copy of the type, that means it&amp;#39;s always going rename types in two files.&amp;nbsp; The side-effect of drag-copy in SE means you *must* manually rename the type in the file you just copied.&amp;nbsp; You can do this with search-replace; but that&amp;#39;s friction I don&amp;#39;t want and really makes SE drag-copy unusable.&lt;/p&gt;
&lt;p&gt;I&amp;#39;ve &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=355239"&gt;logged a bug about it on Connect&lt;/a&gt;; but the olde &amp;quot;by design&amp;quot; card was played... &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1640926" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Product+Bugs/default.aspx">Product Bugs</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Poor+UI/default.aspx">Poor UI</category></item></channel></rss>