tag:blogger.com,1999:blog-223038422024-03-08T10:43:39.283+00:00Something Rather Than NothingWe apologize for the inconvenience.Ian Horwillhttp://www.blogger.com/profile/04971612763190045400noreply@blogger.comBlogger31125tag:blogger.com,1999:blog-22303842.post-15457862670919133732007-02-02T09:31:00.001+00:002007-02-02T09:31:08.682+00:00Session Timeouts - Web Apps' Unaddressed Weakness?<p>This bugs me: I restore an application window from my taskbar, enter a bunch of data, hit "commit" and get taken to the login screen. My data is lost. If I'm incredibly lucky (and think to do it) the app honours the back button and I can login, backup to the screen with the data still in it and recommit.</p> <p>If you take the time, DHTML, Flash, Ajax, etc. can be used to significantly narrow the UX gap between smart client and Web apps, but what can you do about session timeouts?</p> <p>BTW, I'm not a Web developer :-)</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-22303842.post-92071214969383698422007-01-16T12:37:00.001+00:002007-01-16T12:37:10.515+00:00Truth<p>I've been hanging on to this in my inbox for ages so thought I'd put it here. If you love Jack Nicholson's performance in <a href="http://www.imdb.com/title/tt0104257/">A Few Good Men</a>, you'll like this!</p> <p> </p> <p><strong>Programmer</strong>: Jack Nicholson <p><strong>Sales Team</strong>: Tom Cruise <p> <p><strong>Programmer</strong>: You want answers? <p><strong>Sales Team</strong>: I think I'm entitled to them. <p><strong>Programmer</strong>: You want answers?! <p><strong>Sales Team</strong>: I want the truth! <p><strong>Programmer</strong>: You can't HANDLE the truth!! <p>Son, we live in a world that has DATA, CODE AND CONCEPTS. And those ABSTRACT SOLUTIONS have to MAP TO THE REAL WORLD. Who's gonna DESIGN THEM? <p>You? You, MR. SALES TEAM? I have a greater responsibility than you can possibly fathom. You weep for FUNCTIONALITY and you curse the SPEED OF THE SYSTEM. You have that luxury. You have the luxury of not knowing what I know: that these SYSTEMS, while tragic, probably saved lives. And my existence, while grotesque and incomprehensible to you, saves lives...You don't want the truth. Because deep down, in places you don't talk about at parties, you want me on that DESIGN TEAM. <p>You need me on that DESIGN TEAM. <p>We use words like DESIGN, CODE, ANALYSIS...we use these words as the backbone to a life spent PROVIDING ANSWERS AND SOLUTIONS. <p>You use 'em as a punch line. <p>I have neither the time nor the inclination to explain my DESIGN to a man who rises and sleeps under the blanket of the very SOLUTION I provide, then questions the manner in which I provide it! I'd rather you just said thank you and went on your way. Otherwise, I suggest you pick up a CODING LANGUAGE and DESIGN a SYSTEM. Either way, I don't give a damn what you think you're entitled to! <p><strong>Sales Team</strong>: Did you CUT THOSE EXTRA FEATURES? <p><strong>Programmer</strong>: (quietly) I did the job you HIRED me to do. <p><strong>Sales Team</strong>: Did you CUT THOSE EXTRA FEATURES?!! <p><strong>Programmer</strong>: You're goddamn right I did!!</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-22303842.post-25867612475192863952007-01-11T12:21:00.001+00:002007-01-11T12:21:12.885+00:00Microsoft Vista and Office Launch Event<p>Managed to score a place at <a href="https://msevents.microsoft.com/cui/EventDetail.aspx?culture=en-GB&eventid=1032321698">this event</a>! If you did too, there's a geek dinner on the Friday night, organized by <a href="http://www.zimakki.com/blog/">Zi Makki</a>. Sign up <a href="http://www.thehughpage.com/VistaOfficeLaunchGeekDinner">here</a>!</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-22303842.post-52362025561993540892006-11-24T10:21:00.001+00:002006-12-04T11:10:29.119+00:00Forwarding IEnumerable(Of T)<p>Often we have a class that implements IEnumerable by returning the enumerator from an embedded list or array:</p> <div style="font-size: 8pt; background: #ebebff; color: black; font-family: verdana"> <p style="margin: 0px"><span style="color: #2b91af"> 1</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 2</span> <span style="color: blue">Public</span> <span style="color: blue">Class</span> Class1</p> <p style="margin: 0px"><span style="color: #2b91af"> 3</span> <span style="color: blue">Implements</span> IEnumerable</p> <p style="margin: 0px"><span style="color: #2b91af"> 4</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 5</span> <span style="color: blue">Private</span> <span style="color: blue">Function</span> GetEnumerator() <span style="color: blue">As</span> IEnumerator <span style="color: blue">Implements</span> IEnumerable.GetEnumerator</p> <p style="margin: 0px"><span style="color: #2b91af"> 6</span> <span style="color: blue">Return</span> _items.GetEnumerator</p> <p style="margin: 0px"><span style="color: #2b91af"> 7</span> <span style="color: blue">End</span> <span style="color: blue">Function</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 8</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 9</span> <span style="color: blue">Private</span> _items() <span style="color: blue">As</span> <span style="color: blue">Integer</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 10</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 11</span> <span style="color: blue">End</span> <span style="color: blue">Class</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 12</span> </p></div> <p>When I tried to do the same thing with a generic class, I had a problem:</p> <div style="font-size: 8pt; background: #ebebff; color: black; font-family: verdana"> <p style="margin: 0px"><span style="color: #2b91af"> 1</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 2</span> <span style="color: blue">Public</span> <span style="color: blue">Class</span> Class2(<span style="color: blue">Of</span> X <span style="color: blue">As</span> <span style="color: blue">New</span>)</p> <p style="margin: 0px"><span style="color: #2b91af"> 3</span> <span style="color: blue">Implements</span> IEnumerable(<span style="color: blue">Of</span> X)</p> <p style="margin: 0px"><span style="color: #2b91af"> 4</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 5</span> <span style="color: blue">Private</span> <span style="color: blue">Function</span> GetEnumerator() <span style="color: blue">As</span> IEnumerator(<span style="color: blue">Of</span> X) <span style="color: blue">Implements</span> IEnumerable(<span style="color: blue">Of</span> X).GetEnumerator</p> <p style="margin: 0px"><span style="color: #2b91af"> 6</span> <span style="color: blue">Return</span> <span style="color: blue">DirectCast</span>(_items.GetEnumerator, IEnumerator(<span style="color: blue">Of</span> X)) <span style="color: green">'Throws InvalidCastException</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 7</span> <span style="color: blue">End</span> <span style="color: blue">Function</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 8</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 9</span> <span style="color: blue">Private</span> <span style="color: blue">Function</span> GetEnumerator1() <span style="color: blue">As</span> IEnumerator <span style="color: blue">Implements</span> IEnumerable.GetEnumerator</p> <p style="margin: 0px"><span style="color: #2b91af"> 10</span> <span style="color: blue">Return</span> _items.GetEnumerator</p> <p style="margin: 0px"><span style="color: #2b91af"> 11</span> <span style="color: blue">End</span> <span style="color: blue">Function</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 12</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 13</span> <span style="color: blue">Private</span> _items() <span style="color: blue">As</span> X</p> <p style="margin: 0px"><span style="color: #2b91af"> 14</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 15</span> <span style="color: blue">End</span> <span style="color: blue">Class</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 16</span> </p></div> <p>Line 6 throws an exception with the message "Unable to cast object of type 'SZArrayEnumerator' to type 'System.Collections.Generic.IEnumerator`1[System.Int32]'."</p> <p>The answer is simple, but had me scratching my head for a while:</p> <div style="font-size: 8pt; background: #ebebff; color: black; font-family: verdana"> <p style="margin: 0px"><span style="color: #2b91af"> 6</span> <span style="color: blue">Return</span> <span style="color: blue">DirectCast</span>(_items, IEnumerable(<span style="color: blue">Of</span> X)).GetEnumerator</p></div>Anonymousnoreply@blogger.com3tag:blogger.com,1999:blog-22303842.post-9416181983428469822006-11-08T14:53:00.001+00:002006-11-24T14:23:37.613+00:00Numbers Divisible by their Reverse<p>Here is my solution <a href="http://weblogs.asp.net/jgalloway/archive/2006/11/08/Code-Puzzle-_2300_1-_2D00_-What-numbers-under-one-million-are-divisible-by-their-reverse_3F00_.aspx">Jon Galloway's puzzle</a> (my guess was "tens of numbers"):</p> <div style="font-size: 8pt; background: #ebebff; color: black; font-family: verdana"> <p style="margin: 0px"><span style="color: #2b91af"> 1</span> <span style="color: blue">Module</span> Module1</p> <p style="margin: 0px"><span style="color: #2b91af"> 2</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 3</span> <span style="color: blue">Sub</span> Main()</p> <p style="margin: 0px"><span style="color: #2b91af"> 4</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 5</span> <span style="color: blue">Dim</span> testValue <span style="color: blue">As</span> <span style="color: blue">Integer</span> = 21</p> <p style="margin: 0px"><span style="color: #2b91af"> 6</span> <span style="color: blue">Const</span> maxTestValue <span style="color: blue">As</span> <span style="color: blue">Integer</span> = 1000000</p> <p style="margin: 0px"><span style="color: #2b91af"> 7</span> <span style="color: blue">Dim</span> count <span style="color: blue">As</span> <span style="color: blue">Integer</span> = 0</p> <p style="margin: 0px"><span style="color: #2b91af"> 8</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 9</span> <span style="color: blue">Do</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 10</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 11</span> <span style="color: blue">If</span> testValue <span style="color: blue">Mod</span> 10 <> 0 <span style="color: blue">Then</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 12</span> <span style="color: blue">Dim</span> testString <span style="color: blue">As</span> <span style="color: blue">String</span> = testValue.ToString</p> <p style="margin: 0px"><span style="color: #2b91af"> 13</span> <span style="color: blue">Dim</span> reverseString <span style="color: blue">As</span> <span style="color: blue">String</span> = Reverse(testString)</p> <p style="margin: 0px"><span style="color: #2b91af"> 14</span> <span style="color: blue">If</span> reverseString < testString <span style="color: blue">Then</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 15</span> <span style="color: blue">Dim</span> reverseValue <span style="color: blue">As</span> <span style="color: blue">Integer</span> = <span style="color: blue">CInt</span>(reverseString)</p> <p style="margin: 0px"><span style="color: #2b91af"> 16</span> <span style="color: blue">If</span> testValue <span style="color: blue">Mod</span> reverseValue = 0 <span style="color: blue">Then</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 17</span> Console.WriteLine(<span style="color: blue">String</span>.Format(<span style="color: #a31515">"{0} / {1} = {2}"</span>, testValue, reverseValue, testValue / reverseValue))</p> <p style="margin: 0px"><span style="color: #2b91af"> 18</span> count += 1</p> <p style="margin: 0px"><span style="color: #2b91af"> 19</span> <span style="color: blue">End</span> <span style="color: blue">If</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 20</span> <span style="color: blue">End</span> <span style="color: blue">If</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 21</span> <span style="color: blue">End</span> <span style="color: blue">If</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 22</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 23</span> testValue += 1</p> <p style="margin: 0px"><span style="color: #2b91af"> 24</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 25</span> <span style="color: blue">Loop</span> <span style="color: blue">Until</span> testValue > maxTestValue</p> <p style="margin: 0px"><span style="color: #2b91af"> 26</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 27</span> Console.WriteLine(<span style="color: blue">String</span>.Format(<span style="color: #a31515">"{0} numbers <= {1} are non-trivially divisible by their reverse."</span>, count, maxTestValue))</p> <p style="margin: 0px"><span style="color: #2b91af"> 28</span> Console.ReadLine()</p> <p style="margin: 0px"><span style="color: #2b91af"> 29</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 30</span> <span style="color: blue">End</span> <span style="color: blue">Sub</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 31</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 32</span> <span style="color: blue">Private</span> <span style="color: blue">Function</span> Reverse(<span style="color: blue">ByVal</span> value <span style="color: blue">As</span> <span style="color: blue">String</span>) <span style="color: blue">As</span> <span style="color: blue">String</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 33</span> <span style="color: blue">Dim</span> chars() <span style="color: blue">As</span> <span style="color: blue">Char</span> = value.ToCharArray</p> <p style="margin: 0px"><span style="color: #2b91af"> 34</span> Array.Reverse(chars)</p> <p style="margin: 0px"><span style="color: #2b91af"> 35</span> <span style="color: blue">Return</span> <span style="color: blue">New</span> <span style="color: blue">String</span>(chars)</p> <p style="margin: 0px"><span style="color: #2b91af"> 36</span> <span style="color: blue">End</span> <span style="color: blue">Function</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 37</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 38</span> <span style="color: blue">End</span> <span style="color: blue">Module</span></p></div> <p>The .NET limitation is that the String class has no Reverse method!</p> <p>This gives the following rather interesting result:</p> <p><a href="http://i76.photobucket.com/albums/j8/ihorwill/Blog%20Pics/NumbersDivisiblebytheirReverse_CF6B/Capture41.png" atomicselection="true"><img style="margin: 0px" height="100" src="http://i76.photobucket.com/albums/j8/ihorwill/Blog%20Pics/NumbersDivisiblebytheirReverse_CF6B/Capture4_thumb1.png" width="562"></a> </p> <p>It is easily seen that (only) numbers of the format "879*12" and "989*01" (using regex * = 0-or-more occurrences) are solutions to this problem.</p> <p>I have found a rather elegant proof of this but unfortunately it is too large to fit in the margin ;-)</p> <p>I wonder how this generalizes for bases other than 10.</p> <p><strong>Update 9/11/06:</strong></p> <p>Jon's <a href="http://weblogs.asp.net/jgalloway/archive/2006/11/08/Code-Puzzle-_2300_1-_2D00_-Solution.aspx">solution post</a> shows I should have taken the sequence a bit further before jumping to conclusions:</p> <p><a href="http://i76.photobucket.com/albums/j8/ihorwill/Blog%20Pics/NumbersDivisiblebytheirReverse_CF6B/Capture51.png" atomicselection="true"><img height="162" src="http://i76.photobucket.com/albums/j8/ihorwill/Blog%20Pics/NumbersDivisiblebytheirReverse_CF6B/Capture5_thumb1.png" width="566"></a> </p> <p>The pattern now looks like: (879*12)+ or (989*01)+</p> <p>Reminds me of this old puzzle:</p> <p><em>If you have </em>n<em> points on the circumference of a circle, and join them all together with straight lines, how many regions are outlined? (More than two lines may not cross at the same point.)</em></p> <p><a href="http://i76.photobucket.com/albums/j8/ihorwill/Blog%20Pics/NumbersDivisiblebytheirReverse_CF6B/Circles1.png" atomicselection="true"><img height="323" src="http://i76.photobucket.com/albums/j8/ihorwill/Blog%20Pics/NumbersDivisiblebytheirReverse_CF6B/Circles_thumb1.png" width="332"></a> </p> <p>1 point => 1 region<br>2 points => 2 regions<br>3 points => 4 regions<br>4 points => 8 regions</p> <p>n points => 2^(n-1) regions, right?</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-22303842.post-1162316804728967192006-10-31T17:46:00.000+00:002006-11-13T12:50:43.811+00:00You're Shadowing My Stupidity Overload<p>When I wrote my <a href="http://ihorwill.blogspot.com/2006/10/overloads-overloads.html">Overloads vs Shadows</a> post, I was obviously still in the grips of my confusion. One of those times when you think you're being clever, but in fact you're not quite clever enough.</p> <p>Having looked into what the compiler does (and admittedly not much more at the spec), and calmed down a bit, I offer this attempt at clarification.</p> <ul> <li>Within the same "declaration context" (Class, Interface or Module), you can use the same name more than once, as long as at most one of the uses is a typey thing (class, enum, event/delegate), and all the others (which are methods or properties) have different signatures. No keywords are necessary nor can they influence the compiler's behaviour.<br> <li>When considering inherited members with the same name as your own members: <ul> <li>If you're overriding a method/property, that's fine. We all know what that's about. <li>Otherwise, by default, the member in your class <strong>Shadows</strong> all inherited members of the same name. None of the inherited members are accessible except by casting your object reference to the base type. <li>However, if you add the <strong>Overloads</strong> keyword to the member in your derived class, the member only makes inaccessible any base members that have the same signature.</li></ul></li></ul> <p>So the confusion stems (for me at least) from being brought up to believe that <strong>Overloads</strong> means "there are other methods/properties in this class with the same name". Curse you, section 4.1.1!</p> <p>I promise never to use <strong>Overloads</strong> this way again.</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-22303842.post-1162302226048890162006-10-31T13:43:00.000+00:002006-11-13T12:50:43.497+00:00Catch When What?<p>Joe Duffy's <a href="http://www.bluebytesoftware.com/blog/default.aspx">excellent blog</a> has just taught me something (in guideline 16 of <a href="http://www.bluebytesoftware.com/blog/PermaLink,guid,f8404ab3-e3e6-4933-a5bc-b69348deedba.aspx">this article</a>) that I didn't know about structured exception handling in VB.NET, and which is not explained in the <a href="http://www.microsoft.com/downloads/details.aspx?familyid=bf32527d-187c-49fa-8c67-9e9105535550&displaylang=en">language spec</a> (see 10.10.1).</p> <p>What do you think this code should do?</p> <div style="font-size: 8pt; background: #ebebff; color: black; font-family: verdana"> <p style="margin: 0px"><span style="color: #2b91af"> 1</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 2</span> <span style="color: blue">Module</span> Module1</p> <p style="margin: 0px"><span style="color: #2b91af"> 3</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 4</span> <span style="color: blue">Private</span> _value <span style="color: blue">As</span> <span style="color: blue">Integer</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 5</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 6</span> <span style="color: blue">Sub</span> Main()</p> <p style="margin: 0px"><span style="color: #2b91af"> 7</span> _value = 42</p> <p style="margin: 0px"><span style="color: #2b91af"> 8</span> <span style="color: blue">Try</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 9</span> Trouble()</p> <p style="margin: 0px"><span style="color: #2b91af"> 10</span> <span style="color: blue">Catch</span> ex <span style="color: blue">As</span> Exception <span style="color: blue">When</span> _value = 7</p> <p style="margin: 0px"><span style="color: #2b91af"> 11</span> MsgBox(<span style="color: #a31515">"Oh, that's all right then."</span>)</p> <p style="margin: 0px"><span style="color: #2b91af"> 12</span> <span style="color: blue">Catch</span> ex <span style="color: blue">As</span> Exception</p> <p style="margin: 0px"><span style="color: #2b91af"> 13</span> MsgBox(<span style="color: #a31515">"The non-7 value is: "</span> & _value.ToString)</p> <p style="margin: 0px"><span style="color: #2b91af"> 14</span> <span style="color: blue">End</span> <span style="color: blue">Try</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 15</span> <span style="color: blue">End</span> <span style="color: blue">Sub</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 16</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 17</span> <span style="color: blue">Sub</span> Trouble()</p> <p style="margin: 0px"><span style="color: #2b91af"> 18</span> <span style="color: blue">Try</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 19</span> <span style="color: blue">Throw</span> <span style="color: blue">New</span> Exception</p> <p style="margin: 0px"><span style="color: #2b91af"> 20</span> <span style="color: blue">Finally</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 21</span> _value = 7</p> <p style="margin: 0px"><span style="color: #2b91af"> 22</span> <span style="color: blue">End</span> <span style="color: blue">Try</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 23</span> <span style="color: blue">End</span> <span style="color: blue">Sub</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 24</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 25</span> <span style="color: blue">End</span> <span style="color: blue">Module</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 26</span> </p></div> <p>It prints "The non-7 value is: 7" of course.</p> <p>Without a great deal of research (i.e. none) it seems the two passes mentioned by Joe are:</p> <ol> <li>find the target of the exception (i.e. the closest matching catch block on the stack);</li> <li>transfer control to that catch block via each finally block between it and the throw point.</li></ol> <p>Therefore no finally-block code will have executed when the When clause is executed, so invariants could still be broken.</p> <p>No big deal (since exception filters should be kept simple), but worth knowing.</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-22303842.post-1161693613559459182006-10-24T12:40:00.000+00:002006-11-13T12:50:43.118+00:00Overloads Overloads<p>Finally got around to digging into something that's been bugging me since <a href="http://ihorwill.blogspot.com/2006/02/upgrade-fun-moving-to-vs2005.html">February</a>, re the warning message that can be issued by VB.NET in VS2005: "Inappropriate use of 'Overloads' keyword in a module".</p> <p>As related in that post, the Microsoft explanation (from the lovely <a href="http://channel9.msdn.com/ShowPost.aspx?PostID=116718">Amanda Silver</a>) is: "the Overloads keyword only makes a difference to the semantics of the application when the method is overloaded across an inheritance chain". But we all know that an overload is when two methods (properties etc.) share the same name but have different signatures, right? It even says so in the <a href="http://www.microsoft.com/downloads/details.aspx?familyid=bf32527d-187c-49fa-8c67-9e9105535550&displaylang=en">VB language spec</a> (section 4.1.1): "The only way to declare identically named entities of the same kind in a declaration space is through <em>overloading</em>."</p> <p>Ah, but that's the <em>concept</em> called overloading, which is obviously different from the overloading <em>keyword</em>. A few pages further on in the spec (section 4.3.3), all is made clear: "<em>Shadowing by name</em> is specified using the <strong>Shadows</strong> keyword. ... <em>Shadowing by name and signature</em> is specified using the <strong>Overloads</strong> keyword.". I.e. "overloads" is actually overloaded in Visual Basic! And those C# snobs call us stupid ;-)</p> <p>Joking aside, the point is that <strong>Overloads</strong> and <strong>Shadows</strong> are telling the compiler about the relationship between a name in the current class and the same name in base classes, not about the relationship between same-named members within one class. They are saying "this member is not related to members of the same name that I happen to inherit; specifically, it does not override any of them". So actually, these keywords are only necessary when the base member is overridable (i.e. virtual).</p> <p>As mentioned, the difference between the two keywords is that <strong>Overloads</strong> prevents overriding of a specific signature while <strong>Shadows</strong> prevents overriding of anything with the same name; the following code is illegal:</p> <div style="font-size: 8pt; background: #ebebff; color: black; font-family: verdana"> <p style="margin: 0px"><span style="color: #2b91af"> 1</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 2</span> <span style="color: blue">Public</span> <span style="color: blue">Class</span> Class1</p> <p style="margin: 0px"><span style="color: #2b91af"> 3</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 4</span> <span style="color: blue">Public</span> <span style="color: blue">Overridable</span> <span style="color: blue">Sub</span> F(<span style="color: blue">ByVal</span> x <span style="color: blue">As</span> <span style="color: blue">Integer</span>)</p> <p style="margin: 0px"><span style="color: #2b91af"> 5</span> <span style="color: blue">End</span> <span style="color: blue">Sub</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 6</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 7</span> <span style="color: blue">Public</span> <span style="color: blue">Overridable</span> <span style="color: blue">Sub</span> F(<span style="color: blue">ByVal</span> s <span style="color: blue">As</span> <span style="color: blue">String</span>)</p> <p style="margin: 0px"><span style="color: #2b91af"> 8</span> <span style="color: blue">End</span> <span style="color: blue">Sub</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 9</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 10</span> <span style="color: blue">End</span> <span style="color: blue">Class</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 11</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 12</span> <span style="color: blue">Public</span> <span style="color: blue">Class</span> Class2</p> <p style="margin: 0px"><span style="color: #2b91af"> 13</span> <span style="color: blue">Inherits</span> Class1</p> <p style="margin: 0px"><span style="color: #2b91af"> 14</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 15</span> <span style="color: blue">Public</span> <span style="color: blue">Shadows</span> <span style="color: blue">Sub</span> F(<span style="color: blue">ByVal</span> y <span style="color: blue">As</span> <span style="color: blue">Integer</span>)</p> <p style="margin: 0px"><span style="color: #2b91af"> 16</span> <span style="color: blue">End</span> <span style="color: blue">Sub</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 17</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 18</span> <span style="color: blue">Public</span> <span style="color: blue">Overrides</span> <span style="color: blue">Sub</span> F(<span style="color: blue">ByVal</span> s <span style="color: blue">As</span> <span style="color: blue">String</span>)</p> <p style="margin: 0px"><span style="color: #2b91af"> 19</span> <span style="color: blue">MyBase</span>.F(s)</p> <p style="margin: 0px"><span style="color: #2b91af"> 20</span> <span style="color: blue">End</span> <span style="color: blue">Sub</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 21</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 22</span> <span style="color: blue">End</span> <span style="color: blue">Class</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 23</span> </p></div> <p>It generates the error "sub 'F' cannot be declared 'Overrides' because it does not override a sub in a base class." on line 18. Replace <strong>Shadows</strong> with <strong>Overloads</strong> on line 15 and it works just fine.</p> <p>Here's the equivalent in C#, which only has a single keyword for this duty, i.e. <strong>new</strong>:</p> <div style="font-size: 8pt; background: #ebebff; color: black; font-family: verdana"> <p style="margin: 0px"><span style="color: #2b91af"> 1</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 2</span> <span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">Class1</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 3</span> {</p> <p style="margin: 0px"><span style="color: #2b91af"> 4</span> <span style="color: blue">public</span> <span style="color: blue">virtual</span> <span style="color: blue">void</span> F(<span style="color: blue">int</span> x) { }</p> <p style="margin: 0px"><span style="color: #2b91af"> 5</span> <span style="color: blue">public</span> <span style="color: blue">virtual</span> <span style="color: blue">void</span> F(<span style="color: blue">string</span> s) { }</p> <p style="margin: 0px"><span style="color: #2b91af"> 6</span> }</p> <p style="margin: 0px"><span style="color: #2b91af"> 7</span> </p> <p style="margin: 0px"><span style="color: #2b91af"> 8</span> <span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">Class2</span> : <span style="color: #2b91af">Class1</span></p> <p style="margin: 0px"><span style="color: #2b91af"> 9</span> {</p> <p style="margin: 0px"><span style="color: #2b91af"> 10</span> <span style="color: blue">public</span> <span style="color: blue">new</span> <span style="color: blue">void</span> F(<span style="color: blue">int</span> y) { }</p> <p style="margin: 0px"><span style="color: #2b91af"> 11</span> <span style="color: blue">public</span> <span style="color: blue">override</span> <span style="color: blue">void</span> F(<span style="color: blue">string</span> s) { }</p> <p style="margin: 0px"><span style="color: #2b91af"> 12</span> }</p> <p style="margin: 0px"><span style="color: #2b91af"> 13</span> </p></div> <p>This compiles fine, leading us to deduce that <strong>new</strong> is equivalent to <strong>Overloads</strong>. However in <a href="http://www.amazon.com/Applied-Microsoft-NET-Framework-Programming/dp/0735614229">the book</a> on which I cut my .NET teeth (Table 7-4), Jeffrey Richter cites <strong>Shadows</strong> as the VB equivalent of new. </p> <p>Hmm, I wonder... Did <strong>Overloads</strong> start off meaning "I meant to give these methods the same name" but morph into its current meaning when Microsoft realized <strong>Shadows</strong> was a bit too blunt-edged?</p> <hr> <p><strong>Update 31/10/2006</strong></p> <p>I was obviously still confused when I wrote the above post, so I've attempted to straighten it out <a href="http://ihorwill.blogspot.com/2006/10/youre-shadowing-my-stupidity-overload.html">here</a>.</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-22303842.post-1160040943421557152006-10-05T09:35:00.000+00:002006-11-13T12:50:42.074+00:00WithEvents Addendum<p>(Follows on from <a href="http://ihorwill.blogspot.com/2006/10/withevents.html">yesterday's post</a>.)</p> <p>Because WithEvents fields are wrapped in a property, passing them by reference is should be a problem, but it magically seems to work! This is an example of VB.NET continuing in its fine tradition of "protecting" the developer from messy details. </p> <p><a href="http://www.aisto.com/roeder/dotnet/">Reflector</a> reveals that if you write this:</p> <div style="font-size: 8pt; background: #ebebff; color: black; font-family: verdana"> <p style="margin: 0px"><span style="color: blue">Friend</span> <span style="color: blue">WithEvents</span> Button1 <span style="color: blue">As</span> System.Windows.Forms.Button</p> <p style="margin: 0px"> </p> <p style="margin: 0px"><span style="color: blue">Private</span> <span style="color: blue">Sub</span> X()</p> <p style="margin: 0px"> Y(Button1)</p> <p style="margin: 0px"><span style="color: blue">End</span> <span style="color: blue">Sub</span></p> <p style="margin: 0px"> </p> <p style="margin: 0px"><span style="color: blue">Private</span> <span style="color: blue">Sub</span> Y(<span style="color: blue">ByRef</span> a <span style="color: blue">As</span> Button)</p> <p style="margin: 0px"><span style="color: blue">End</span> <span style="color: blue">Sub</span></p></div> <p>the VB compiler generates code for X() like this:</p> <div style="font-size: 8pt; background: #ebebff; color: black; font-family: verdana"> <p style="margin: 0px"><span style="color: blue">Private</span> <span style="color: blue">Sub</span> X()</p> <p style="margin: 0px"> <span style="color: blue">Dim</span> button1 <span style="color: blue">As</span> Button = <span style="color: blue">Me</span>.Button1</p> <p style="margin: 0px"> <span style="color: blue">Me</span>.Y(button1)</p> <p style="margin: 0px"> <span style="color: blue">Me</span>.Button1 = button1</p> <p style="margin: 0px"><span style="color: blue">End</span> <span style="color: blue">Sub</span></p></div>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-22303842.post-1159963943981218142006-10-04T12:12:00.000+00:002006-11-13T12:50:41.629+00:00Suspending WithEvents Handlers<p>Sometimes you want to call methods on a WinForms control (for example) but not have it raise events, e.g. to prevent recursive calls. For handlers you've added yourself with AddHandler, the answer is obvious: remove the handler and re-add it when you've done your thing. However, in VB you've usually got automatically generated event handlers hooked up to WithEvents fields with the Handles keyword. What do you do about these? Is it OK to call Remove/AddHandler in the usual way?</p> <p>(BTW I think the alternative technique of setting an "ignore events" flag is to be discouraged because it has to be tested in all of the handlers; by using Add/RemoveHandler you're keeping the code close to the point that requires it.)</p> <p>The WithEvents section in the <a href="http://www.microsoft.com/downloads/details.aspx?familyid=bf32527d-187c-49fa-8c67-9e9105535550">Language Spec</a> is quite revealing on this point.</p> <p>Basically, if you declare a WithEvents variable called x, what you actually get is a private variable called _x and a property called x that looks like this:</p> <div style="font-size: 8pt; background: #ebebff; color: black; font-family: verdana"> <p style="margin: 0px"><span style="color: blue">Friend</span> <span style="color: blue">Overridable</span> <span style="color: blue">Property</span> x() <span style="color: blue">As</span> TextBox</p> <p style="margin: 0px"> <span style="color: blue">Get</span></p> <p style="margin: 0px"> <span style="color: blue">Return</span> _x</p> <p style="margin: 0px"> <span style="color: blue">End</span> <span style="color: blue">Get</span></p> <p style="margin: 0px"> <span style="color: blue">Set</span>(<span style="color: blue">ByVal</span> value <span style="color: blue">As</span> TextBox)</p> <p style="margin: 0px"> <span style="color: blue">If</span> _x <span style="color: blue">IsNot</span> <span style="color: blue">Nothing</span> <span style="color: blue">Then</span></p> <p style="margin: 0px"> <span style="color: green">'Remove handlers from _x</span></p> <p style="margin: 0px"> <span style="color: blue">End</span> <span style="color: blue">If</span></p> <p style="margin: 0px"> _x = value</p> <p style="margin: 0px"> <span style="color: blue">If</span> _x <span style="color: blue">IsNot</span> <span style="color: blue">Nothing</span> <span style="color: blue">Then</span></p> <p style="margin: 0px"> <span style="color: green">'Add handlers to _x</span></p> <p style="margin: 0px"> <span style="color: blue">End</span> <span style="color: blue">If</span></p> <p style="margin: 0px"> <span style="color: blue">End</span> <span style="color: blue">Set</span></p> <p style="margin: 0px"><span style="color: blue">End</span> <span style="color: blue">Property</span></p></div> <p>The list of handlers to add and remove is generated from all the methods that have a "Handles" clause for an event of this instance. If a WithEvents field has no handlers, the wrapper property is still generated but its setter simply sets the value of the hidden field.</p> <p>Knowing this, you can temporarily suspend all event handling (other than via handlers you explicitly added yourself) with code like this:</p> <div style="font-size: 8pt; background: #ebebff; color: black; font-family: verdana"> <p style="margin: 0px"><span style="color: blue">Dim</span> temp <span style="color: blue">As</span> TextBox = x</p> <p style="margin: 0px">x = <span style="color: blue">Nothing</span></p> <p style="margin: 0px">temp.AppendText() <span style="color: green">'Anything that would normally raise an event</span></p> <p style="margin: 0px">x = temp</p></div> <p>Caveat: the code between setting x to Nothing and restoring it can't call any methods that need to access x; also, this code should be wrapped in a Try/Finally to make sure the field is always reset to its original value.</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-22303842.post-1158828901240730572006-09-21T08:55:00.000+00:002006-11-13T12:50:40.890+00:00.NET Assembly Resolution<p>Thanks to .NET, DLL Hell is officially ended. But I at least still find myself in DLL Heck from time to time (thanks to <a href="http://dilbertblog.typepad.com/the_dilbert_blog/">Scott Adams</a> for the term).</p> <p>We still seem to have too many issues where something works on one machine but not on another (usually it works on the developer's machine but not when we install it on a director's laptop to show him that we haven't spent the last month just browsing the Internet).</p> <p>Our app has a simple footprint: we bung everything, including third-party controls, into a bin folder. How can anything go wrong? The loader looks in the app folder for stuff first, doesn't it? WRONG!</p> <p>We get away this simple-minded view most of the time because (and I know you'll tell me off for this) we aren't yet strongly naming our assemblies. In this case, the loader <em>only</em> looks in the app folder (and below).</p> <p>But for strongly named assemblies, the loader <strong>looks in the GAC first</strong>. This makes sense. The loader is always looking for a specific version of an assembly; you control which assembly versions are loaded for your app via the version policy, not by shadowing shared DLLs with your own copies in the app bin folder.</p> <p>Here are some links that explain all this unambiguously.</p> <p><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconassemblyversioning.asp">Assembly Versioning</a> (from the MSDN Library)</p> <p><a href="http://www.awprofessional.com/articles/article.asp?p=30601&seqNum=6&rl=1">Resolving Names to Locations</a> (from .NET Common Language Runtime Components by Don Box & Chris Sells)</p> <p>Useful diagram from the second link:</p> <p><a href="http://i76.photobucket.com/albums/j8/ihorwill/Blog%20Pics/ccafd2b9c594.NETAssemblyResolution_895E/02fig124.gif" atomicselection="true"><img height="582" src="http://i76.photobucket.com/albums/j8/ihorwill/Blog%20Pics/ccafd2b9c594.NETAssemblyResolution_895E/02fig12_thumb4.gif" width="455"></a> </p> <p>Bonus information from that book extract: if you put <developmentMode developerInstallation="true" /> in the configuration/runtime node of the machine.config file, the loader first looks in the path specified by the DEVPATH environment variable.</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-22303842.post-1157734235445018322006-09-08T16:50:00.000+00:002006-11-13T12:50:40.406+00:00HTTP Partial Get - The Point<p>Got so into blogging the "how" in the last post that I forgot about the "why", although I hope that's fairly obvious.</p> <p>The W3C puts it like <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3">this</a>:</p> <p><font face="MS Reference Sans Serif" size="1">The partial GET method is intended to reduce unnecessary network usage</font></p> <p>and <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.2">this</a>:</p> <p><font face="MS Reference Sans Serif" size="1">A server MAY ignore the Range header. However, HTTP/1.1 origin servers and intermediate caches ought to support byte ranges when possible, since Range supports efficient recovery from partially failed transfers, and supports efficient partial retrieval of large entities.</font></p> <p>I.e.</p> <ol> <li>Keep the Internet clean (hear that, spammers?)</li> <li>Speed up client requests.</li></ol> <p>I'm sure I had a point, but it's gone. The thought of all the crap floating around in the ether has depressed me too much to think. I think I need to see Marvin to cheer me up.</p> <p>BTW our web hosting company honours ranges so perhaps it's not all that bad.</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-22303842.post-1157732668344072552006-09-08T16:24:00.000+00:002006-11-13T12:50:40.062+00:00HTTP Partial Get<p>Part of our application allows the user to drag/drop document links onto a window. When the link is a web page shortcut, I wanted to get the page title as the description for that link. The only way I could find to do this was to download the page using an HttpWebRequest object, and parse for the <title> tag.</p> <p>This is OK except that I didn't want to download an entire page just to get a piece of information that, if present, will be somewhere near the top. Enter the <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3" target="_blank">partial get</a> capability of HTTP 1.1. If you add a "range" header to the GET request, the server should return only the specified byte range from the document. Here is the code I used.</p> <p> <div style="font-size: 8pt; background: #ebebff; color: black; font-family: verdana"> <p style="margin: 0px"> </p> <p style="margin: 0px"> <span style="color: blue">Private</span><span style="color: blue">Function</span> GetWebPageTitle(<span style="color: blue">ByVal</span> url <span style="color: blue">As</span> <span style="color: blue">String</span>) <span style="color: blue">As</span> <span style="color: blue">String</span></p> <p style="margin: 0px"> </p> <p style="margin: 0px"> <span style="color: blue">Dim</span> request <span style="color: blue">As</span> HttpWebRequest</p> <p style="margin: 0px"> <span style="color: blue">Dim</span> response <span style="color: blue">As</span> WebResponse</p> <p style="margin: 0px"> <span style="color: blue">Const</span> bytesToGet <span style="color: blue">As</span> <span style="color: blue">Integer</span> = 1000</p> <p style="margin: 0px"> </p> <p style="margin: 0px"> request = <span style="color: blue">DirectCast</span>(WebRequest.Create(url), HttpWebRequest)</p> <p style="margin: 0px"> request.AddRange(0, bytesToGet - 1)</p> <p style="margin: 0px"> response = request.GetResponse</p> <p style="margin: 0px"> </p> <p style="margin: 0px"> ...</p> <p style="margin: 0px"> </p> <p style="margin: 0px"> <span style="color: blue">End</span><span style="color: blue">Function</span></p> <p style="margin: 0px"> </p></div> <p>However, the operative word here is <em>should</em> (i.e. it's not mandatory behaviour). In half-a-dozen web sites I tried (including microsoft.com), only one took any notice of my range request:</p> <p><a href="http://i76.photobucket.com/albums/j8/ihorwill/Blog%20Pics/HTTPPartialGet_F31D/Wireshark7.png" atomicselection="true"><img height="249" src="http://i76.photobucket.com/albums/j8/ihorwill/Blog%20Pics/HTTPPartialGet_F31D/Wireshark_thumb7.png" width="400"></a> </p> <p>Some things to note:</p> <ul> <li>The response code is 206 (Partial Content) <li>Content-Length = 1000 <li>Content-Range = 0-999 (the first 1000 bytes) of a total of 126,444 <li>Accept-Ranges: Bytes tells us the server recognizes the Range header in the GET request (which we now know, but we could have issued a HEAD request to find this out) <li>The well-behaved web site is w3.org (of course!)</li></ul> <p>(The screenshot is from <a href="http://www.wireshark.org/">Wireshark</a>, formerly Ethereal.)</p>Anonymousnoreply@blogger.com1tag:blogger.com,1999:blog-22303842.post-1156870863899064142006-08-29T17:01:00.000+00:002006-11-13T12:50:39.441+00:00Windows Live Writer<p>If you can see this, I've successfully started using <a href="http://windowslivewriter.spaces.live.com/">Windows Live Writer</a>, and should hopefully start blogging more, now it's a bit easier.</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-22303842.post-1147814627935757942006-05-16T21:23:00.000+00:002006-11-13T12:50:38.733+00:00Why the Fancy UI?<p>I recently subscribed to <a href="http://www.thejoyofcode.com/">the Joy of Code blog</a> which I am liking a lot, and <a href="http://www.thejoyofcode.com/Why_the_fancy_UI_.aspx">this post</a> struck a chord with me. The thrust of the article is that software vendors shouldn't waste time tarting up their interfaces: what we need is standard, functional interfaces. While I agree that these "flashy" UIs can be very frustrating, or even unusable, I enjoy seeing an app go beyond the ordinary and try something different. Arguably the most successful company at not following the "Microsoft way" is of course <a href="http://www.microsoft.com/office/preview/suites/basic/overview.mspx">Microsoft</a>:</p><img alt="Microsoft Money" src="http://i76.photobucket.com/albums/j8/ihorwill/Blog%20Pics/WhyTheFancyUI/f4d81ec1.png" border="0" /> <p>To answer the rhetorical question, I guess development teams at virus scanner companies have pretty much done the hard stuff, so have time to work on differentiating themselves from the competitors. Still if you're just trying to get something done, a <a href="http://thedailywtf.com/forums/thread/22257.aspx">plain, simple, intuitive UI</a> is what you need.</p>Anonymousnoreply@blogger.com1tag:blogger.com,1999:blog-22303842.post-1145604913567201522006-04-21T07:35:00.000+00:002006-11-13T12:50:38.442+00:00Development Philosophy<p class="mobile-post">When I write code, I usually try to imagine all the conditions under which the code will run, what can fail, etc., and write code or add comments to handle or describe these conditions. I am sure I am not alone in this and that there are a number of formalized procedures that promote this.<br /> <br />I am wondering if this is becoming an "old fashioned" way to program.<br />The modern way seems to be to bash out code as fast as possible without thinking too much, and fix problems as they arise. I expect this is not entirely new, but rather is simply becoming more common, and perhaps even more accepted. In fact the whole agile thing seems to address how one can code in this fashion but still end up with good code.<br /> <br />I am suddenly suspicious that I am in danger of losing touch, and becoming an "old fogey" in coding terms. Not because I don't keep up with my reading (I do) but because deep down I am still holding on to old ideals and methods.<br /> <br />Still, they say that half of fixing a problem is recognizing you have it :-)</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-22303842.post-1142178608272203622006-03-12T15:50:00.000+00:002006-11-13T12:50:38.248+00:00Reflection Over Generic Types - Follow-UpVenkat (who gave the DNR TV presentation) <a href="http://www.agiledeveloper.com/blog/PermaLink,guid,8d26ddb5-8357-4372-b0e3-499f6e99adfe.aspx">follows up</a> with some more details.Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-22303842.post-1142083362456571432006-03-11T13:22:00.000+00:002006-11-13T12:50:37.854+00:00Reflection Over Generic Types - Bug?<p>Inspired by a <a href="http://www.dnrtv.com/0009/index.html">episode #9</a> of <a href="http://www.dnrtv.com/">DNR TV</a>, I ran the following program to see the type info for a generic base class, where the type parameter is passed from the derived class, and was unpleasantly surprised by the result:</p> <div style='font-family:verdana;font-size: 8pt;background-color: gainsboro;'> <br/> </span><span style='color:black'> </span><span style='color:Blue'>Public Class</span><span style='color:black'> Base(</span><span style='color:Blue'>Of</span><span style='color:black'> T)<br/> </span><span style='color:Blue'>End Class<br/> <br/> </span><span style='color:black'> </span><span style='color:Blue'>Public Class</span><span style='color:black'> Derived(</span><span style='color:Blue'>Of</span><span style='color:black'> T)<br/> </span><span style='color:Blue'>Inherits</span><span style='color:black'> Base(</span><span style='color:Blue'>Of</span><span style='color:black'> T)<br/> </span><span style='color:Blue'>End Class<br/> <br/> </span><span style='color:Blue'>Public Class</span><span style='color:black'> Program<br/> <br/> </span><span style='color:Blue'>Shared Sub</span><span style='color:black'> Main()<br/> DisplayInfo(</span><span style='color:Blue'>GetType</span><span style='color:black'>(Base(</span><span style='color:Blue'>Of Integer</span><span style='color:black'>)), 0)<br/> DisplayInfo(</span><span style='color:Blue'>GetType</span><span style='color:black'>(Derived(</span><span style='color:Blue'>Of Integer</span><span style='color:black'>)), 0)<br/> </span><span style='color:Blue'>End Sub<br/> <br/> </span><span style='color:black'> </span><span style='color:Blue'>Private Shared Sub</span><span style='color:black'> DisplayInfo(</span><span style='color:Blue'>ByVal</span><span style='color:black'> type </span><span style='color:Blue'>As</span><span style='color:black'> Type, </span><span style='color:Blue'>ByVal</span><span style='color:black'> indent </span><span style='color:Blue'>As Integer</span><span style='color:black'>)<br/> WriteLine(type.Name, indent)<br/> WriteLine(type.FullName, indent)<br/> </span><span style='color:Blue'>If</span><span style='color:black'> type.IsGenericType </span><span style='color:Blue'>Then<br/> </span><span style='color:black'> WriteLine(</span><span style='color:Maroon'>"Yes, it's generic baby!"</span><span style='color:black'>, indent)<br/> </span><span style='color:Blue'>If Not</span><span style='color:black'> type.IsGenericTypeDefinition </span><span style='color:Blue'>Then<br/> </span><span style='color:black'> WriteLine(</span><span style='color:Maroon'>"and here's its generic type def:"</span><span style='color:black'>, indent)<br/> DisplayInfo(type.GetGenericTypeDefinition, indent + 1)<br/> </span><span style='color:Blue'>End If<br/> </span><span style='color:black'> </span><span style='color:Blue'>Else<br/> </span><span style='color:black'> WriteLine(</span><span style='color:Maroon'>"It's not generic, man!"</span><span style='color:black'>, indent)<br/> </span><span style='color:Blue'>End If<br/> </span><span style='color:black'> </span><span style='color:Blue'>If</span><span style='color:black'> type.BaseType </span><span style='color:Blue'>IsNot GetType</span><span style='color:black'>(</span><span style='color:Blue'>Object</span><span style='color:black'>) </span><span style='color:Blue'>Then<br/> </span><span style='color:black'> WriteLine(</span><span style='color:Maroon'>"and here's its base type:"</span><span style='color:black'>, indent)<br/> DisplayInfo(type.BaseType, indent + 1)<br/> </span><span style='color:Blue'>End If<br/> </span><span style='color:black'> </span><span style='color:Blue'>End Sub<br/> <br/> </span><span style='color:black'> </span><span style='color:Blue'>Private Shared Sub</span><span style='color:black'> WriteLine(</span><span style='color:Blue'>ByVal</span><span style='color:black'> s </span><span style='color:Blue'>As String</span><span style='color:black'>, </span><span style='color:Blue'>ByVal</span><span style='color:black'> indent </span><span style='color:Blue'>As Integer</span><span style='color:black'>)<br/> Debug.Write(Space(indent * 4))<br/> Debug.WriteLine(s)<br/> </span><span style='color:Blue'>End Sub<br/> <br/> </span><span style='color:black'> </span><span style='color:Blue'>End Class<br/> <br/> </span> </div> <br/><p>Here's the output:</p> <div style='font-family:monospace;font-size: 8pt;background-color: khaki;'> <br/> 1 Base`1<br> 2 WindowsApplication1.Indent.Base`1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]<br> 3 Yes, it's generic baby!<br> 4 and here's its generic type def:<br> 5 Base`1<br> 6 WindowsApplication1.Indent.Base`1<br> 7 Yes, it's generic baby!<br> 8 Derived`1<br> 9 WindowsApplication1.Indent.Derived`1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]<br> 10 Yes, it's generic baby!<br> 11 and here's its generic type def:<br> 12 Derived`1<br> 13 WindowsApplication1.Indent.Derived`1<br> 14 Yes, it's generic baby!<br> 15 and here's its base type:<br> 16 Base`1<br> 17<br> 18 Yes, it's generic baby!<br> 19 and here's its generic type def:<br> 20 Base`1<br> 21 WindowsApplication1.Indent.Base`1<br> 22 Yes, it's generic baby!<br> 23 and here's its base type:<br> 24 Base`1<br> 25 WindowsApplication1.Indent.Base`1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]<br> 26 Yes, it's generic baby!<br> 27 and here's its generic type def:<br> 28 Base`1<br> 29 WindowsApplication1.Indent.Base`1<br> 30 Yes, it's generic baby!<br> <br/></div> <br/><p>The problem is with the blank line on line 17. The base of the open generic class definition for Derived has no full name! Presumably line 17 should show the same as line 6. If you change Derived(Of T) to inherit from Base(Of Double) for example, all is fine.</p> Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-22303842.post-1140192663602885532006-02-17T16:10:00.000+00:002006-11-13T12:50:36.999+00:00Upgrade Fun - Moving to VS2005<p>Following on from my <a href="http://ihorwill.blogspot.com/2005/06/upgrading-to-whidbey-beta-2.html">first post</a>, we are now starting to upgrade for real and trying to get rid of those warnings. This is being hampered by the background compiler: every time I fix up a bit of code off it goes, hogging my CPU, until it has gone through the entire solution I guess. A search on the MSDN forums turns up this from MS guy Matthew Gertz:</p><blockquote>"The background compiler cannot be turned off in Visual Basic .Net – it’s actually the thing that’s providing all of the Intellisense information, formatting information, and so on. I discuss this in some detail <a href="http://msdn.microsoft.com/msdnmag/issues/05/06/AdvancedBasics/default.aspx">here</a>. In that article are some tips to improve performance in larger-scale applications."</blockquote><p>To minimize this problem, I am opening our projects one by one (bottom-up in the reference tree) instead of all at once in our monster solution. In fact, I think our development is going to have to continue this way until the background compiler's performance (or at least its perceived performance) is greatly improved.</p><p><strong>Using an instance variable to access a shared member (Error ID: BC42025)</strong></p><p>I would like to turn this warning off rather than fix it, because using a short<br />variable name in place of a sometimes quite long class name can reduce clutter and<br />make the code easier to read. However one of the ways we do this is we declare an<br />instance of an enum type (nested in another class) to provide short-cut access to<br />the enum literals, which results in an "unused variable" warning which I definitely<br />don't want to turn off.</p><p>Fortunately, initializing the enum variable removed the "unused" warning, at least in this compiler version. This is fortunate because the warning was also occurring when accessing members of the DialogResult enumeration on a form: Form also has a DialogResult property which hides the enum so you end up having to fully qualify it (or partially qualify it if you import a parent namespace, e.g. System.Windows).</p><p><b>Getting out of bad VB6 habits, and other details</b></p><p>The new compiler is much more fussy (a Good Thing) at pointing out poor form, including:</p><ul><li>Not explictly initializing reference variables if they are going to be used before an assignment;</li><br /><li>Not explictly returning Nothing from a function (a variant of this is having return statements inside a Select - you're then forced to define an "else" clause, which is another Good Thing);</li><br /><li>Leaving unused variable declarations lying around.</li><br /></ul><p>Mind you, the explicit initializer thing is a bit of a pain when you're only going to initialize it to Nothing anyway. I've gotten too used to seeing lack of an initializer as an invisible Nothing or 0 (note the compiler doesn't fuss about default initialization of value types - why the inconsistency?) Also, the parser doesn't recognize patterns such as this, and reports that ref is used before being initialized:</p><br /><code class="code"><span class="keyword"> Dim</span> isFirstTime <span class="keyword">As Boolean</span> = <span class="keyword">True</span><br /><span class="keyword"> Dim</span> ref <span class="keyword">As</span> SomeClass<br /><span class="keyword"> For</span> i <span class="keyword">As Integer</span> = 0 <span class="keyword">To</span> 10<br /><span class="keyword"> If</span> isFirstTime <span class="keyword">Then</span><br /> ref = SomeMethod()<br /> isFirstTime = <span class="keyword">False</span><br /><span class="keyword"> Else</span><br /><span class="comment"> 'use ref</span><br /><span class="keyword"> End If<br /> Next</span><br /></code><br /><p>Another annoying variant of this is "Variable 'XXX' is passed by reference before it has been assigned a value. A null reference exception could result at runtime." This is annoying when you are passing by reference because the method is going to initialize the variable. This is a weakness of ByRef in VB: it means "in/out" and we have no keyword to specify just "out".</p><p><b>Proper XML commenting - Hooray!</b></p><p>We had had a half-hearted attempt to add these in using the VBCommenter add-in in Visual Studio 2003, but stopped when we found Intellisense wasn't picking up our descriptions. We've now got to fix syntax errors (invalid whitespace), mismatched param elements etc. in the existing comments.</p><p>I am getting a strange error though: "XML documentation parse error: "Whitespace is not allowed at this location. XML comment will be ignored." This is being reported <i>inside</i> the summary element. I.e. I can cut all the lines between <summary> and </summary> and it is fine, but when I paste the original text back (which contains no XML or anything obviously funky), the error springs back.</p><p>D'oh - the summary text contained an ampersand! So it seems like it is a real XML document fragment.</p><p><b>Inappropriate use of 'Overloads' keyword in a module</b></p><p>This surprised me. The help link merely says that modules aren't classes and therefore can't use MustInherit etc., blah, blah. Nothing about why Overloads is invalid on Module members. You can use it on Shared class members, so what's the problem? Amanda Silver <a href="http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=653c832a-b8de-4105-87fc-622bb64778ae">explains</a>:</p><blockquote>We decided to give this warning because the application of the Overloads keyword only makes a difference to the semantics of the application when the method is overloaded across an inheritance chain. As the Overloads is superfluous in the context of a Module (and possibly misleading) we decided to emit a warning. Note, however, that the warning can be turned off by going to the project properties and selecting the "Disable all warnings" check box.</blockquote><br /><p>I love the last sentence!</p><p>I need to revise the purpose of Overloads and Shadows to fully understand this, but I would have thought that if you get a warning for Module members, you should get one for Shared class members too. Stay tuned.</p><p><b>Name '_blah' is not CLS-compliant</b></p><p>In a number of places, we have protected fields which, because they are fields, begin with an underscore. Because protected members are exposed outside the assembly and therefore available to other assemblies, they should be CLS-compliant (which means they can't begin with an underscore). The easiest way round this, since we don't need to interop with other .NET languages, is to mark the entire assembly as not CLS compliant in Assembly.vb.</p>Anonymousnoreply@blogger.com6tag:blogger.com,1999:blog-22303842.post-1140166363684852142006-02-17T08:52:00.000+00:002006-11-13T12:50:36.836+00:00Keeping Your Friends CloseI don't like the "Friend" access modifier in VB.NET ("internal" in C#) because it provides a very sloppy kind of access control, allowing as it does any method in the entire assembly to access the Friend type or member.<br /><br />In C++ you could (I suppost "can" would be better, but I don't think I'll be using C++ very much in the future) explicitly specify who your friends are, to the class or even method (or top-level function) level, which means you keep control over the interfaces to your class.<br /><br />From a library writer's perspective (when looking at the library as a whole at least), Friend is somewhat useful because it lets you separate "us" from "them", but when you're writing in-house code and trying to design coherent public and proptected interfaces, Friends can become your enemies.<br /><br />Especially since we are encouraged to write "big" assemblies to reduce load times and so can't use the assembly as a fine-grained partitioning mechanism for tightly coupled classes.<br /><br />What would be nice is a namespace-like mechanism to allow you to group classes together into friendships, so that only classes in the same friendship group have access to each other's Friend members.<br /><br />Namespaces themselves can't be used of course, because anyone can add additional types to a namespace.<br /><br />But you could say that Friend members where only accessible from type in the same assembly <em>and</em> namespace. Or, better, allow the Friend keyword to be used on a namespace declaration to mean "Friends within this namespace aren't accessible outside it" (obviously the "same assembly" restriction would still hold). The good thing with this approach is that if you don't use it you get the current behaviour.<br /><br />What do you think <a href="http://panopticoncentral.net/">Mr. Vick</a>?<br /><br /><strong>Update</strong><br /><br />Having proudly e-mailed Paul Vick my suggestion, I blushingly realized that what I should have done is enter it via the "Make a Suggestion" link on the <a href="http://lab.msdn.microsoft.com/productfeedback/">MSDN product feedback page</a>. When I started to do that I found several other suggestions along the same lines (i.e. reintroducing C++ style friend specifiers), but none I think as simple as mine, although I have conveniently ignored how these friend namespaces should be managed across multiple source files in the same assembly - i.e. should you be made to specify "friend" for all of them, or should doing it once automatically apply to all; perhaps it is analagous to partial classes. Also I didn't think of the work that would be needed in the CLR; after all, namespaces are just syntactic sugar, right? Yeah, but friend/internal isn't! Sometimes I wish I'd just keep my (e-)mouth shut.<br /><br /><strong>Update #2</strong><br /><br />Paul Vick replied on 26th Feb:<br /><br />Hey, Ian, I apologize for taking so long to write back! More granular Friend control is definitely something that's been requested in a number of different ways and it's something we'll definitely look at as we plan our next release. It's definitely a matter of trying to balance the need for control versus the need to keep the concept count down as much as possible, always a delicate trade off.<br />Thanks for making the suggestion and thanks for using VB!<br />PaulAnonymousnoreply@blogger.com0tag:blogger.com,1999:blog-22303842.post-1139917620135005972006-02-14T11:45:00.000+00:002006-11-13T12:50:36.693+00:00Synchronize Class View in VS2005<p>Wanted to give this some more Google-juice (though I don't think even the Google spider reads my blog) because the help docs lie:</p><br /><a href="http://blogs.msdn.com/ansonh/archive/2005/12/09/502020.aspx">http://blogs.msdn.com/ansonh/archive/2005/12/09/502020.aspx</a>Anonymousnoreply@blogger.com2tag:blogger.com,1999:blog-22303842.post-1139912727808081112006-02-14T10:09:00.000+00:002006-11-13T12:50:36.413+00:00A Quote for New BloggersWhen you start a blog it is with high hopes that your fantastic insight and wit will garner a steadily growing readership, with occasional rapid rises when some blog-ebrity links to you from his blog.<br /><br />Sadly this is not generally the case, and you either give up in defeat, or relegate your blog to a personal diary. Alternatively you can image that there really are hundreds, nay thousands, of appreciative readers who are just too shy to leave comments.<br /><br />With a few notable exceptions (see, a good blogger would put some links in here) most of the popular blogs out there are popular because they are written by well-known speakers or authors (and I'm being parochial here, I've no idea what happens in blogs I don't read).<br /><br />And here's why (and finally the point of this post):<br /><br /><a href="http://www.quotationspage.com/quote/1984.html">http://www.quotationspage.com/quote/1984.html</a><br /><br />P.S. if anyone is reading this blog, please excuse posts mysteriously appearing "in the past"; I'm pulling stuff together that I've already posted elsewhere, or queued to post, and I want to keep the original dates on stuff. This is a personal diary after all!Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-22303842.post-1139746072759070042005-10-31T22:15:00.000+00:002006-11-13T12:50:35.963+00:00Dear Mr. VickI wanted to lend some support to a great idea I heard from <a href="http://www.panopticoncentral.net/">Paul Vick</a> on <a href="http://www.dotnetrocks.com/default.aspx?showID=135">.NET Rocks!</a><br /> <br /> "Heard you on .NET Rocks! mention the possibility of doing away with VB's line continuation character - presumably making it more C-like in its treatment of whitespace. I think this would be GREAT!<br /> <br /> "I have come to VB from a long history of C and C++ and (especially with VB.NET) the only think that has really niggled is VB's line-oriented parser.<br /> <br /> "I expect you'll have to pull off some pretty neat tricks with context-sensitive parsing but please, please please do it!"Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-22303842.post-1139757174680798802005-10-28T14:37:00.000+00:002006-11-13T12:50:36.153+00:00SQL SurpriseGot tripped up by this little bit of SQL (which I naively bashed out in Query Analyzer):<br /><br />select * from Addresses where AddrID in<br />(select AddrID from BankAccounts where BankID=234255)<br /><br />The BankAccounts table includes a foreign key to Addresses, giving the address of the branch at which the account is held (there is no intermediate BankBranches table). So I was expecting this query to give me one row from Addresses (or perhaps none). In fact, it gave me the whole damn table.<br /><br />The problem is that the BankAccounts table doesn't have an AddrID column; it's called BankAddrID. So why didn't the query give an error? I'm no SQL expert but basically it's because the outer select is in scope (which allows correlated subqueries to work) so the query I wrote was effectively:<br /><br />select AddrID from Addresses<br />cross join BankAccounts<br />where BankID=234255<br /><br />D'oh!Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-22303842.post-1139745673176750262005-09-15T13:44:00.000+00:002006-11-13T12:50:35.735+00:00Philosophical DevelopmentNice <a href="http://weblogs.asp.net/rosherove/archive/2005/09/15/425232.aspx">rant</a> from <a href="http://weblogs.asp.net/rosherove/">Roy Osherove</a>. The esoteric work is necessary up front to make the whole thing hang together properly, and you should be able to drill down into it if you find that useful or interesting, but it shouldn't pollute the mainstream information. What we need there are more problem-focussed discussions and less BS!Anonymousnoreply@blogger.com0