<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.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>Introducing the for-if anti-pattern</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2011/12/27/10251210.aspx</link><description>We'll sell you the whole seat, but you'll only need the edge.</description><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>re: Introducing the for-if anti-pattern</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2011/12/27/10251210.aspx#10252544</link><pubDate>Tue, 03 Jan 2012 01:59:20 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10252544</guid><dc:creator>Joshua</dc:creator><description>&lt;p&gt;[Trust me on this -- the code that used the for-if anti-pattern was not doing so because it was worried about short names. (The actual example was not a file system query but a database query.) -Raymond]&lt;/p&gt;
&lt;p&gt;Filed under: completely missing the point (not Raymond, but everybody else). This changes just about everything.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10252544" width="1" height="1"&gt;</description></item><item><title>re: Introducing the for-if anti-pattern</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2011/12/27/10251210.aspx#10252185</link><pubDate>Sat, 31 Dec 2011 06:39:03 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10252185</guid><dc:creator>Gabe</dc:creator><description>&lt;p&gt;Joshua: FindFirstFile always returns a long name along with the short name if it exists, and GetFiles just uses that behind the scenes.&lt;/p&gt;
&lt;p&gt;As of W7 and WS2008R2, FindFirstFileEx can be passed FindExInfoBasic to have it not query the short names, so you can avoid the short names if your OS supports it.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10252185" width="1" height="1"&gt;</description></item><item><title>re: Introducing the for-if anti-pattern</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2011/12/27/10251210.aspx#10252151</link><pubDate>Sat, 31 Dec 2011 00:46:49 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10252151</guid><dc:creator>Jim</dc:creator><description>&lt;p&gt;Re: short names (and maybe other related filesystem quirks)&lt;/p&gt;
&lt;p&gt;Surely this is another problem with the for-if anti-pattern, rather than something it does right? I mean, if the filename is &amp;quot;longfi~1.txt&amp;quot; instead of &amp;quot;desktop.ini&amp;quot;, presumably the intended behaviour would be that the routine succeeds, which the for-if anti-pattern doesn&amp;#39;t. (And again, in this case it would be even better to &amp;quot;just go ahead and do it, and catch the exception if it doesn&amp;#39;t work&amp;quot;.)&lt;/p&gt;
&lt;p&gt;Having said that, it does prove that there&amp;#39;s a difference in behaviour, and so it&amp;#39;s possible in principle that the for-if anti-pattern would have better results in some situations.&lt;/p&gt;
&lt;div class="post"&gt;[&lt;i&gt;Trust me on this -- the code that used the for-if anti-pattern was not doing so because it was worried about short names. (The actual example was not a file system query but a database query.) -Raymond&lt;/i&gt;]&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10252151" width="1" height="1"&gt;</description></item><item><title>re: Introducing the for-if anti-pattern</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2011/12/27/10251210.aspx#10251967</link><pubDate>Fri, 30 Dec 2011 04:51:44 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10251967</guid><dc:creator>Joshua</dc:creator><description>&lt;p&gt;Phaeron above is right. Calling GetFiles() avoids short-name collisions as it won&amp;#39;t return any short names.&lt;/p&gt;
&lt;p&gt;Too bad there&amp;#39;s no option to the wildcard expansion to FindFirstFile to avoid them. However, the way GetFiles() works, is it returns the long name for any file matching by shortname to wildcard (I don&amp;#39;t know if Find*File always returns the long name or if .NET&lt;/p&gt;
&lt;p&gt;makes another call) so simply repeating the match in the code fixes the problem.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10251967" width="1" height="1"&gt;</description></item><item><title>re: Introducing the for-if anti-pattern</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2011/12/27/10251210.aspx#10251809</link><pubDate>Thu, 29 Dec 2011 18:29:15 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10251809</guid><dc:creator>sambeet</dc:creator><description>&lt;p&gt;I am not so sure that i can write this off as an absolute anti pattern. of course, if you are not breaking from the loop, it is a problem. But consider the coding / real life scenarios:&lt;/p&gt;
&lt;p&gt;1. What if you are given a list and are asked to operate on a specific element. I cannot assume that the list is always hashed. Depending on the size of the list and / or frequency of execution of my logic, i may simply decide to iterate till i find the right item. I would not blindly assume that i need to hash the list every time because, hashing comes at the expense of additional memory and one time processing.&lt;/p&gt;
&lt;p&gt;2. Going to your flavor logic, lets assume that all flavors are on the display and there is no server [this is a true representation of the concept]. Are you not going to go through the list till you see the flavour you want? NOW, lets assume the person being present at the counter. I do not have to spend time looking at an extensive menu display. i can simply ask the server. HERE, the server IS my hash in a way.&lt;/p&gt;
&lt;p&gt;So, in sort, this is a bad practice but only if&lt;/p&gt;
&lt;p&gt;1. if you own the list in your code&lt;/p&gt;
&lt;p&gt;2. frequently need to operate on a specific element&lt;/p&gt;
&lt;p&gt;3. Do not have member contract considerations to implement hashing&lt;/p&gt;
&lt;div class="post"&gt;[&lt;i&gt;Obviously not every enumeration falls into for-if anti-pattern. Only the ones where the container provides direct addressing. -Raymond&lt;/i&gt;]&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10251809" width="1" height="1"&gt;</description></item><item><title>re: Introducing the for-if anti-pattern</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2011/12/27/10251210.aspx#10251759</link><pubDate>Thu, 29 Dec 2011 15:15:33 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10251759</guid><dc:creator>Chris B</dc:creator><description>&lt;p&gt;&amp;quot;You also see this anti-pattern used in real life: &amp;#39;What flavors do you have?&amp;#39; and then after the list of flavors is recited, &amp;#39;I was hoping you had raspberry.&amp;#39;&amp;quot;&lt;/p&gt;
&lt;p&gt;For-if might be a reasonable method in this case. &amp;nbsp;The customer may believe that the odds of the provider having raspberry are low, and must therefore choose an alternative. If the provider&amp;#39;s options are unknown and the odds are high that the entire list will need to be recited, it may not optimize the scenario to ask if raspberry is available before asking for the list. &amp;nbsp;The customer may also be in a situation where raspberry sounds good now, but might hear something that sounds better (I can&amp;#39;t think of a situation where this would happen in computing, but it works in this analogy).&lt;/p&gt;
&lt;p&gt;You could also imagine scenarios where the customer had multiple preferred options; something like &amp;quot;I was hoping for raspberry, blueberry, or strawberry.&amp;quot; Depending on what options are available to make that determination, it may be more efficient to just ask for the list and see if one of the preferred options is there. &amp;nbsp;Doing so may even free the provider to service other requests while the customer is making a decision. &amp;nbsp;This is fairly close to what happens when a server at a restaurant hands you a menu.&lt;/p&gt;
&lt;p&gt;The questions I would try to answer before deciding on the best approach are:&lt;/p&gt;
&lt;p&gt;1. How long are the customer and provider&amp;#39;s lists?&lt;/p&gt;
&lt;p&gt;2. How often do they change?&lt;/p&gt;
&lt;p&gt;3. How often will each list need to be queried/compared?&lt;/p&gt;
&lt;p&gt;4. What is the cost of communication between the customer and provider?&lt;/p&gt;
&lt;p&gt;5. What methods does the provider support to answer the customer&amp;#39;s questions?&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10251759" width="1" height="1"&gt;</description></item><item><title>re: Introducing the for-if anti-pattern</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2011/12/27/10251210.aspx#10251586</link><pubDate>Wed, 28 Dec 2011 21:23:09 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10251586</guid><dc:creator>Raphael</dc:creator><description>&lt;p&gt;Well, I can think of an Ada example where the for-case pattern makes sense. Since a case must include all values of a given type, doing a for over the full range of a type and then a case inside it would make sure to handle all values in that range.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10251586" width="1" height="1"&gt;</description></item><item><title>re: Introducing the for-if anti-pattern</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2011/12/27/10251210.aspx#10251537</link><pubDate>Wed, 28 Dec 2011 16:34:24 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10251537</guid><dc:creator>JM</dc:creator><description>&lt;p&gt;&amp;quot;Regarding the question of using a dictionary to look up a value. That&amp;#39;s all well and good if you already have a dictionary, but if all you have available is an array, then iterating through the array to find the one element you need to do something to will be quicker than building a dictionary in order to do one single lookup on it.&amp;quot;&lt;/p&gt;
&lt;p&gt;That goes without saying, so I didn&amp;#39;t say it. Don&amp;#39;t make me bring back the nitpicker&amp;#39;s corner.&lt;/p&gt;
&lt;p&gt;Wait, I don&amp;#39;t have one and this isn&amp;#39;t even my blog. Never mind.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10251537" width="1" height="1"&gt;</description></item><item><title>re: Introducing the for-if anti-pattern</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2011/12/27/10251210.aspx#10251532</link><pubDate>Wed, 28 Dec 2011 16:03:28 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10251532</guid><dc:creator>Nick Lowe</dc:creator><description>&lt;p&gt;In addition to the race, the BCL&amp;#39;s File.Exists() method is of limited value as it can only confirm that a file exists at a location, not that it does not exist. (It&amp;#39;s the same with Directory.Exists().)&lt;/p&gt;
&lt;p&gt;This is because File.Exists() does not discriminate between a file not existing and an underlying error condition that prevents the existence of a file being determined. It returns false in both cases.&lt;/p&gt;
&lt;p&gt;What has been implemented is not Exists() semantics, it is IsAccessible() semantics, and only in the instant that you call it. You cannot assume that it is still accessible after due to the race.&lt;/p&gt;
&lt;p&gt;So... just try and open the file and handle the FileNotFoundException exception.&lt;/p&gt;
&lt;p&gt;So... just try and open the file and handle the exception.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10251532" width="1" height="1"&gt;</description></item><item><title>re: Introducing the for-if anti-pattern</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2011/12/27/10251210.aspx#10251530</link><pubDate>Wed, 28 Dec 2011 15:59:46 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10251530</guid><dc:creator>Nick Lowe</dc:creator><description>&lt;p&gt;If you do want to see if a non-directory file exists in .NET as opposed to checking if it&amp;#39;s accesible to the application:&lt;/p&gt;
&lt;p&gt;public static bool FileExists(string path)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;try&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return (File.GetAttributes(path) &amp;amp; (FileAttributes.Directory | FileAttributes.Device)) == 0;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;catch (FileNotFoundException)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return false;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;And for a directory file:&lt;/p&gt;
&lt;p&gt;public static bool DirectoryExists(string path)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;try&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return (File.GetAttributes(path) &amp;amp; FileAttributes.Directory) != 0;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;catch(FileNotFoundException)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return false;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10251530" width="1" height="1"&gt;</description></item></channel></rss>