<?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>jaredpar's WebLog : VB</title><link>http://blogs.msdn.com/jaredpar/archive/tags/VB/default.aspx</link><description>Tags: VB</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Dev Connection Talk Slides and Code</title><link>http://blogs.msdn.com/jaredpar/archive/2009/12/02/dev-connection-talk-slides-and-code.aspx</link><pubDate>Wed, 02 Dec 2009 21:21:45 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9931627</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/9931627.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=9931627</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=9931627</wfw:comment><description>&lt;p&gt;Thanks to everyone who attended my sessions at Dev Connections.&amp;#160; I’ve posted the material for both of my talks on my SkyDrive account.&amp;#160; This includes the slides and projects.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://cid-dc25b20f65f628f8.skydrive.live.com/browse.aspx/Public/DevConnections2009"&gt;http://cid-dc25b20f65f628f8.skydrive.live.com/browse.aspx/Public/DevConnections2009&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Please let me know if you have any questions or problems with the materials or any additional feedback about the sessions.&amp;#160; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9931627" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/VB/default.aspx">VB</category></item><item><title>Speaking at Dev Connections in Las Vegas Next Week</title><link>http://blogs.msdn.com/jaredpar/archive/2009/11/03/speaking-at-dev-connections-in-las-vegas-next-week.aspx</link><pubDate>Tue, 03 Nov 2009 16:51:04 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9916831</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/9916831.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=9916831</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=9916831</wfw:comment><description>&lt;p&gt;Next week I will be speaking at &lt;a href="http://www.devconnections.com/shows/FALL2009VS/default.asp?s=136"&gt;Dev Connections&lt;/a&gt; in Las Vegas.&amp;#160; I will be running the following sessions&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;VMS02: Future Directions for Visual Basic&lt;/li&gt;    &lt;li&gt;VMS04: Microsoft Visual Basic IDE Tips and Tricks&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Both of these talks will spend a bit of time talking about all of the progress and exciting new features we’ve added in Dev10.&amp;#160; Given I primarily work on the IDE these days, expect a bit of IDE content to work it’s way into the Future Directions talk as well.&amp;#160; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9916831" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/VB/default.aspx">VB</category></item><item><title>Why is LINQ absent from debugger windows?</title><link>http://blogs.msdn.com/jaredpar/archive/2009/08/26/why-no-linq-in-debugger-windows.aspx</link><pubDate>Wed, 26 Aug 2009 15:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9877055</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/9877055.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=9877055</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=9877055</wfw:comment><description>&lt;p&gt;As the owner of the VB.Net portion of the overall debugging experience, I frequently hear the request from customers to add LINQ support into the Watch / Immediate and Locals window.&amp;nbsp; Virtually every other type of expression is available in the debugger windows so why leave one of the most popular ones out? &lt;/p&gt;  &lt;p&gt;Quick Diversion: the specifics of this article are written from the point of view of the VB.Net expression evaluator.&amp;nbsp; However, the limitations blocking LINQ support (in both the architecture and overall design) are very similar between VB.Net and C#.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;As usual, the primary issue is cost and the cost for LINQ in the debugger windows is very high.&amp;nbsp; To understand why the cost is so high though, we must start by getting a better understanding how a language service interacts with the debugging services of Visual Studio and the general philosophy around compiler features in the debugger.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;Languages in Visual Studio typically provide the following major components to support the debugging experience.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;p&gt;Expression Evaluator (EE): This is the language specific component which provides all of the data used in the watch, locals and immediate window, data tips, conditional breakpoints and several other components.&amp;nbsp; It’s primary input is an expression in string form which is converted to a value (typically an ICorDebugValue instance) and outputs a COM object capable of inspecting that value to the core debugger [1].&amp;nbsp;&amp;nbsp; Everything typed into the debugger windows goes through the EE.&lt;/p&gt;      &lt;p&gt;This component lives in the MTA of Visual Studio and has almost no interaction with the UI / STA thread. &lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;ENC Service: This is the component which is the work horse of ENC operations.&amp;nbsp; It provides rude edit detection, metadata differencing and metadata + IL generation&amp;nbsp;&amp;nbsp; .&lt;/p&gt;      &lt;p&gt;This component lives in the main STA of Visual Studio&lt;/p&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The important thing to understand about the expression evaluator is that it’s purpose is primarily to provide an expression evaluation and data inspection service.&amp;nbsp; How expression evaluation works is an article in itself but suffice it to say that it converts the string to a very low level AST then walks the nodes bottom up and evaluating the expressions using the ICorDebug APIs.&amp;nbsp; The EE component has no UI and is simply a data provider for the core debugger services.&amp;nbsp;&amp;nbsp; &lt;/p&gt;  &lt;p&gt;The design philosophy for Both VB.Net and C# is to have the highest level of fidelity between expressions evaluated in the EE and the actual running program.&amp;nbsp; To do otherwise would lead to extremely confusing results for users.&amp;nbsp; When spec’ing feature support in the VB.Net EE we start from the point of 100% fidelity, determine the problems with this design (if any) and then start the difficult process of making compromises.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;LINQ expressions are very different than any other expression previously allowed in the EE window because of the features interaction with metadata.&amp;nbsp; All LINQ expressions require the generation or manipulation of metadata to support the underlying lambda and/or closure.&amp;nbsp; Adding support for this is one of the biggest hurdles to getting LINQ (and other features) into the EE.&amp;nbsp;&amp;nbsp; &lt;/p&gt;  &lt;p&gt;Evaluating a LINQ expression is actually much closer to an ENC operation than a traditional EE one.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;Currently the EE’s have no capacity for generating metadata, only interpreting it.&amp;nbsp; Operations which mutate or generate metadata have traditionally only been allowed via the ENC service.&amp;nbsp; Getting LINQ to work in the EE with true fidelity would require at least a minimal amount of ENC feature work.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;Without getting into too much detail, lets enumerate the&lt;b&gt; new&lt;/b&gt; major features necessary to evaluate a LINQ expression in the EE with true fidelity to the running program.&amp;nbsp; To simplify things, we’ll start by assuming there is no other LINQ expression used in the current method and the method is only being executed at most once at any given time in the process.&amp;nbsp;&amp;nbsp; &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;A metadata generation service to support the backing for closures and lambda expressions &lt;/li&gt;    &lt;li&gt;Convert expressions typed in the EE into IL [2] &lt;/li&gt;    &lt;li&gt;ENC support for metadata to push the new metadata for closures and lambdas into the currently executing assembly &lt;/li&gt;    &lt;li&gt;ENC support for method body IL to remove lifted variables from the current method and redirect the references inside the closure&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Issues #1 and #2 are for the most part internal architecture issues and can be solved via normal processes of code base refactoring and adding new features to an existing component.&amp;nbsp;&amp;nbsp; I don’t mean to imply these problems are cheap (in fact they are relatively expensive)&amp;nbsp; But fixing these is somewhat of an understood quantity.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;Issues #3 and #4 are where the problems start.&amp;nbsp; As implemented EE’s do not have capability to create or modify metadata in the running process (that is the job of the ENC service).&amp;nbsp; EE’s do have access to the underlying CLR ENC APIs so it is possible to implement ENC operations in the EE.&amp;nbsp; It’s just simply not been done yet.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;Wait!&amp;nbsp; Why not reuse our ENC implementation in the EE?&amp;nbsp; Unfortunately the ENC service is currently tied heavily to our in memory IDE compiler and many other IDE / STA features.&amp;nbsp; It in fact lives in a completely separate DLL, separate COM apartment and works on a different symbol table than the EE.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;More fundamental though is that it’s designed for a completely different purpose.&amp;nbsp; ENC is designed to track edits in live code, determining the differences and applying them to the running program.&amp;nbsp; The hypothetical EE feature would be tracking expressions that modify a running DLL for which code is not guaranteed (and not likely) to be available and applying the difference to the running program.&amp;nbsp; There are some similarities but the differences are significant enough to make code reuse have limited value.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;Some people may wonder why it’s necessary to implement #4.&amp;nbsp; Couldn’t we just avoid removing the variable from the current method and make the feature cheaper?&amp;nbsp; This is possible but it would cause a significant fidelity difference in the feature.&amp;nbsp; Any mutations of the local variable within the LINQ expression would not be visible on the stack frame as it would if the LINQ expression was present in the original program.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;It’s easy to think of this ENC in the EE as just the same type of cost as #1 and #2 (in many ways it is).&amp;nbsp; However taking advantage of the CLR ENC APIs in the EE also means that we inherit it’s limitations as well.&amp;nbsp; ENC as as implemented in the CLR has many limitations which fly in the face of LINQ.&amp;nbsp; In particular the following ENC limitations present major problems (&lt;a mce_href="http://blogs.msdn.com/jmstall/archive/2005/02/19/376666.aspx" href="http://blogs.msdn.com/jmstall/archive/2005/02/19/376666.aspx"&gt;ENC limitations reference&lt;/a&gt;).&amp;nbsp; &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Cannot add members to a value type.&amp;nbsp; This prevents evaluating LINQ when stopped in a value type method &lt;/li&gt;    &lt;li&gt;Cannot remove locals from a function.&amp;nbsp; This is an implementation of LINQ but we could work around this problem by changing the IL to simply no longer accessing the local variables. &lt;/li&gt;    &lt;li&gt;Cannot change anything in a generic type.&amp;nbsp; This prevents evaluating LINQ when stopped in a generic type.&amp;nbsp; &lt;/li&gt;    &lt;li&gt;Cannot specify an initial value for newly added fields. &lt;/li&gt;    &lt;li&gt;Allowable ENC operations differ between the top of the stack and operations elsewhere within the stack &lt;/li&gt;    &lt;li&gt;Modification of a non-top stack frame cannot significantly edit the current function call.&amp;nbsp; So if a LINQ expression captures a variable used in that call (think ref passing) it would likely be unable to be evaluated.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;So even if we implemented everything possible on the language service side the resulting feature would be limited in several impactful ways.&amp;nbsp; Additionally these limitations are somewhat orthogonal to the current limitations EE’s face and would require a bit of user education.&amp;nbsp; And this is only for the most basic LINQ feature under unrealistic scenarios.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;Lets now consider the problems of evaluating a LINQ expression when the current method already contains a LINQ expression that lifts at least 1 variable.&amp;nbsp; Evaluating a new expression at the same scope would require the modification of the current closure to maintain fidelity as opposed to generating a new one.&amp;nbsp; This brings along with it a couple more problems.&amp;nbsp; &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;     &lt;p&gt;A lambda expression which uses 2 variables, 1 of which is captured in an existing lambda expression.&amp;nbsp; To maintain fidelity we would have to modify an existing closure signature to contain the new variable. &lt;/p&gt;      &lt;p&gt;&amp;nbsp;&lt;/p&gt;      &lt;p&gt;Often times generated closures are generic so we would run straight into ENC limitation #3. Additionally we would need the newly added field to have the same value as it has in the current method which runs us into ENC limitation #4. Now also consider that a closure instance can live much longer than the method in which it was created. For those closures no stack value is available so what value should we give fields in that instance?&amp;nbsp; Ideally it should have the value of the variable at the point the method exited but realistically that’s not possible.&amp;nbsp; &lt;/p&gt;      &lt;p&gt;&amp;nbsp;&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;A lambda expression which uses 1 variable in a method where an existing lambda expression captures that same variable and another.&amp;nbsp; To maintain fidelity we would have to know about this and fake capture the second variable as well.&lt;/p&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Now consider all of the problems above and consider the scenario where there are multiple threads and multiple instances of the current method active in the program.&amp;nbsp; How to determine which closure instance belongs to which thread, and just as important which stack frame on which thread, with respect to initializing values?&lt;/p&gt;  &lt;p&gt;None of the issues are an unsolvable problem but they do represent a significant cost to the feature.&amp;nbsp; And once again even if we added all of these features to the EE, ENC limitations would significantly limit the usefulness of the resulting feature.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;Does this mean that LINQ, or any future metadata requiring expression, will never be added to the debugger window?&amp;nbsp; Absolutely not.&amp;nbsp; We’ve just hit the difficult stage of making compromises on the level of fidelity in the feature.&amp;nbsp; If you back off of true fidelity in a few small ways the resulting feature, while still very expensive, is significantly cheaper and removes many of the limitations imposed by ENC.&amp;nbsp;&amp;nbsp; This &lt;b&gt;hypothetical&lt;/b&gt; feature will be discussed in my next article.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;[1] For those interested the returned interface is &lt;a mce_href="http://msdn.microsoft.com/en-us/library/bb161287(VS.80).aspx" href="http://msdn.microsoft.com/en-us/library/bb161287(VS.80).aspx"&gt;IDebugProperty2&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;[2] Right now expressions are converted to a tree form slightly above IL and they are interpreted using the ICorDebug APIs.&amp;nbsp; Converting all the way down to IL requires a lot more work&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9877055" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Closures/default.aspx">Closures</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Debugging/default.aspx">Debugging</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Lambda/default.aspx">Lambda</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/LINQ/default.aspx">LINQ</category></item><item><title>Extension Methods and ByRef targets</title><link>http://blogs.msdn.com/jaredpar/archive/2008/12/11/extension-methods-and-byref-targets.aspx</link><pubDate>Thu, 11 Dec 2008 16:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9189036</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/9189036.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=9189036</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=9189036</wfw:comment><description>&lt;p&gt;One of the seldom used, and often unknown, features of VB extension methods is that the argument of the extension method (the first parameter) can be passed by reference.&amp;#160; This gives extension methods the power to change the reference that was used to invoke the value!&amp;#160; &lt;/p&gt;  &lt;p&gt;Obviously this can produce unexpected but often amusing behavior.&amp;#160; The following sample prints “False”.&lt;/p&gt;  &lt;pre class="code"&gt;    &amp;lt;Extension()&amp;gt; _
    &lt;span style="color: blue"&gt;Public Sub &lt;/span&gt;EnsureNotNull(&lt;span style="color: blue"&gt;ByRef &lt;/span&gt;str &lt;span style="color: blue"&gt;As String&lt;/span&gt;)
        &lt;span style="color: blue"&gt;If &lt;/span&gt;str &lt;span style="color: blue"&gt;Is Nothing Then
            &lt;/span&gt;str = &lt;span style="color: blue"&gt;String&lt;/span&gt;.Empty
        &lt;span style="color: blue"&gt;End If
    End Sub

    Sub &lt;/span&gt;Example(&lt;span style="color: blue"&gt;ByVal &lt;/span&gt;p1 &lt;span style="color: blue"&gt;As String&lt;/span&gt;)
        p1.EnsureNotNull()
        Console.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;{0}&amp;quot;&lt;/span&gt;, p1 &lt;span style="color: blue"&gt;Is Nothing&lt;/span&gt;)
    &lt;span style="color: blue"&gt;End Sub

    Sub &lt;/span&gt;Main()
        Example(&lt;span style="color: blue"&gt;Nothing&lt;/span&gt;)
    &lt;span style="color: blue"&gt;End Sub
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;I think people will look at this example and either cringe, call it terrible code or get excited.&amp;#160; Personally I’m somewhere between cringing and getting excited (in fact I’m doing both).&amp;#160; But before people think I’ve gone off the deep end I don’t plan on checking this in any time soon (and yes I think it’s a bad idea).&lt;/p&gt;

&lt;p&gt;Why?&amp;#160; The feature is fun to play with and can create some interesting samples but it can also just as easily lead to very bad and unanticipated behavior.&amp;#160; For instance what if instead of making sure something wasn’t Nothing, the code made the argument Nothing?&amp;#160; &lt;/p&gt;

&lt;pre class="code"&gt;&amp;lt;Extension()&amp;gt; _
&lt;span style="color: blue"&gt;Sub &lt;/span&gt;EvilMethod(&lt;span style="color: blue"&gt;ByRef &lt;/span&gt;p1 &lt;span style="color: blue"&gt;As Object&lt;/span&gt;)
    p1 = &lt;span style="color: blue"&gt;Nothing
End Sub

Sub &lt;/span&gt;Example2()
    &lt;span style="color: blue"&gt;Dim &lt;/span&gt;s &lt;span style="color: blue"&gt;As New &lt;/span&gt;Student()
    s.PrintClass()
    s.EvilMethod()
    s.PrintName()   &lt;span style="color: green"&gt;' Causes a NullReferenceException
&lt;/span&gt;&lt;span style="color: blue"&gt;End Sub&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;The code runs and throws an exception.&amp;#160; A developer attaches a debugger, looks at the exception but immediately notes there are 2 other method calls just above.&amp;#160; How could they succeed but the last throw a NullReferenceException???&amp;#160; Certainly this may be a fun joke but in production code a fellow developer would not be amused.&amp;#160; &lt;p&gt;More importantly though the behavior when passing an extension method target by reference is flat out unexpected.&amp;#160; Who expects what appears to an instance method call to be able to modify “Me/this?”&amp;#160; Probably not too many people.&amp;#160; Coding is difficult enough without creating patterns that will blow away anyone who owns your code down the line.&amp;#160; Code should do it’s best to be clear and produce predictable results.&lt;/p&gt;

&lt;p&gt;Still, an interesting feature to toy with. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9189036" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Extension+Methods/default.aspx">Extension Methods</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Humor/default.aspx">Humor</category></item><item><title>Properly handling a WinForms Timer event</title><link>http://blogs.msdn.com/jaredpar/archive/2008/10/27/properly-handling-a-winforms-timer-event.aspx</link><pubDate>Mon, 27 Oct 2008 15:00:07 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9017488</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/9017488.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=9017488</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=9017488</wfw:comment><description>&lt;p&gt;The WinForms &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.aspx"&gt;Timer&lt;/a&gt; class allows the user to perform a particular action at a set interval.&amp;#160; Timer objects fire a &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.tick.aspx"&gt;Tick&lt;/a&gt; event at the set time which users can easily respond to.&amp;#160; This is very useful if a developer wants to check for a particular condition say every 2 seconds ( for the remainder of this article I'm going to use 2 seconds as a practical example even though it's really any arbitrary time period).&lt;/p&gt;  &lt;p&gt;Occasionally users are surprised to find that the Tick event will fire much faster than they are expecting.&amp;#160; Instead of waiting for 2 seconds between calls, they event will fire almost immediately after one is finished processing. &lt;/p&gt;  &lt;p&gt;What's going on here is a side effect of how this event works under the hood.&amp;#160; The interval for the timer event is calculated in real world time.&amp;#160; So quite literally every 2 seconds Windows will consider the internal reached and will issue a new tick message.&amp;#160; The next time a WinForms event is not executing developer code a tick event is raised [1].&amp;#160; &lt;/p&gt;  &lt;p&gt;So imagine we had the following code.&amp;#160; &lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Private Sub &lt;/span&gt;OnTimerTick() &lt;span style="color: blue"&gt;Handles &lt;/span&gt;m_timer.Tick
    RunSomeOperation()
&lt;span style="color: blue"&gt;End Sub&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Consider what happens if RunSomeOperation takes longer than 2 seconds.&amp;#160; The Tick event is fired in real time so while we're in the middle of RunSomeOperation, another Tick event is being queued up for processing.&amp;#160; As soon as we leave OnTimerTick we're back in WinForms code which sees a Tick event and promptly raises it which puts us right back in OnTimerTick.&lt;/p&gt;

&lt;p&gt;This is contrary to what most people expect.&amp;#160; Most people expect the Tick event to fire 2 seconds after their code is finished executing.&amp;#160; &lt;/p&gt;

&lt;p&gt;To work around this developers should stop the timer when processing a timer event.&amp;#160; Just before exiting the event handler, re-enable the timer.&amp;#160; This will cause Windows to start calculating the interval from the start.&amp;#160; This has the effect of making the timer event fire 2 seconds after developer code stops executing.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Private Sub &lt;/span&gt;OnTimerTick() &lt;span style="color: blue"&gt;Handles &lt;/span&gt;m_timer.Tick
    m_timer.Stop()
    &lt;span style="color: blue"&gt;Try
        &lt;/span&gt;RunSomeOperation()
    &lt;span style="color: blue"&gt;Finally
        &lt;/span&gt;m_timer.Start()
    &lt;span style="color: blue"&gt;End Try
End Sub&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;[1] This is not 100% true.&amp;#160; It's really whenever the Application begins to pump messages again.&amp;#160; Message pumping, more specifically when it does and does not occur, is too involved for this discussion.&amp;#160; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9017488" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/WinForms/default.aspx">WinForms</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Gotcha/default.aspx">Gotcha</category></item><item><title>VB Catch ... When: Why so special?</title><link>http://blogs.msdn.com/jaredpar/archive/2008/10/09/vb-catch-when-why-so-special.aspx</link><pubDate>Thu, 09 Oct 2008 15:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8990446</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/8990446.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=8990446</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=8990446</wfw:comment><description>&lt;P&gt;The VB Catch syntax has a particular feature not present in C#: When.&amp;nbsp; It allows users to filter expressions based on something other than their type.&amp;nbsp; Any arbitrary code can enter a When block to decide whether or not to handle an Exception&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN style="COLOR: blue"&gt;Sub &lt;/SPAN&gt;Sub1()
        &lt;SPAN style="COLOR: blue"&gt;Try
            &lt;/SPAN&gt;DoSomeAction()
        &lt;SPAN style="COLOR: blue"&gt;Catch &lt;/SPAN&gt;ex &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;Exception &lt;SPAN style="COLOR: blue"&gt;When &lt;/SPAN&gt;Filter(ex)
            &lt;SPAN style="COLOR: blue"&gt;Stop
        End Try
    End Sub
&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Newsgroups often ask, "Why's this so special? I could effectively get the same behavior out of C# by doing the following."&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;static void &lt;/SPAN&gt;Sub1()
{
    &lt;SPAN style="COLOR: blue"&gt;try
    &lt;/SPAN&gt;{
        DoSomeAction();
    }
    &lt;SPAN style="COLOR: blue"&gt;catch &lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;Exception &lt;/SPAN&gt;ex)
    {
        &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(Filter(ex))
        {
            &lt;SPAN style="COLOR: blue"&gt;throw&lt;/SPAN&gt;;
        }
        HandleException();
    }
}&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;This is true to an extent.&amp;nbsp; In both cases the code is handling an exception and making a decision, via calling Filter, as to whether or not to handle the exception.&amp;nbsp; The subtle difference is when the Filter method is called.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;In VB the When statement is actually implemented as an IL exception filter.&amp;nbsp; When an exception is thrown, exception filters are processed before the stack is unwound.&amp;nbsp; This means that if the Filter method created an error report that included the current stack trace, it would show the frame in which the exception occurred.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;For example, in the code above if DoSomeAction() threw and the stack was examined in the Filter expression, the following stack would show up. &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/jaredpar/WindowsLiveWriter/VBCatch.WhenWhysospecial_1299E/image_2.png" mce_href="http://blogs.msdn.com/blogfiles/jaredpar/WindowsLiveWriter/VBCatch.WhenWhysospecial_1299E/image_2.png"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; BORDER-TOP: 0px; BORDER-RIGHT: 0px" border=0 alt=image src="http://blogs.msdn.com/blogfiles/jaredpar/WindowsLiveWriter/VBCatch.WhenWhysospecial_1299E/image_thumb.png" width=504 height=304 mce_src="http://blogs.msdn.com/blogfiles/jaredpar/WindowsLiveWriter/VBCatch.WhenWhysospecial_1299E/image_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Notice how the DoSomeAction method is clearly visible?&amp;nbsp; This is incredibly powerful for features like error reporting and investigation.&amp;nbsp; It also allows you to set powerful breakpoints where the exact state of the error can be examined and not just the post mortem.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Alternatively, code executed in the C# block will occur after the stack is unwound.&amp;nbsp; This gets rid of the culprit.&amp;nbsp; As long as your not in optimized code you can usually use the stack trace properties to get the source of the exception but you won't be able to examine the live state of the error. &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/jaredpar/WindowsLiveWriter/VBCatch.WhenWhysospecial_1299E/image_4.png" mce_href="http://blogs.msdn.com/blogfiles/jaredpar/WindowsLiveWriter/VBCatch.WhenWhysospecial_1299E/image_4.png"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; BORDER-TOP: 0px; BORDER-RIGHT: 0px" border=0 alt=image src="http://blogs.msdn.com/blogfiles/jaredpar/WindowsLiveWriter/VBCatch.WhenWhysospecial_1299E/image_thumb_1.png" width=501 height=304 mce_src="http://blogs.msdn.com/blogfiles/jaredpar/WindowsLiveWriter/VBCatch.WhenWhysospecial_1299E/image_thumb_1.png"&gt;&lt;/A&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8990446" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>First MSDN article</title><link>http://blogs.msdn.com/jaredpar/archive/2008/08/18/first-msdn-article.aspx</link><pubDate>Mon, 18 Aug 2008 15:00:10 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8848428</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/8848428.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=8848428</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=8848428</wfw:comment><description>&lt;p&gt;The August issue of MSDN magazine will be carrying an article I wrote this spring.&amp;#160; In it I toy around with using the deferred execution and lazy evaluation properties of LINQ to create more responsive UI code.&amp;#160; &lt;/p&gt;  &lt;p&gt;You can view the article &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc721610.aspx"&gt;here&lt;/a&gt;.&amp;#160; &lt;/p&gt;  &lt;p&gt;As usual I appreciate any feedback you have.&amp;#160; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8848428" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Misc/default.aspx">Misc</category></item><item><title>Making Equality easier</title><link>http://blogs.msdn.com/jaredpar/archive/2008/06/03/making-equality-easier.aspx</link><pubDate>Tue, 03 Jun 2008 15:00:10 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8569777</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/8569777.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=8569777</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=8569777</wfw:comment><description>&lt;p&gt;Recently I've done a bit of posting about the difficulties of &lt;a href="http://blogs.msdn.com/jaredpar/archive/2008/05/12/equality-isn-t-easy.aspx"&gt;properly implementing equality&lt;/a&gt; &lt;a href="http://blogs.msdn.com/jaredpar/archive/2008/04/28/properly-implementing-equality-in-vb.aspx"&gt;in VB&lt;/a&gt; (and DotNet in general).&amp;nbsp; While most of the problems can be fixed with a standard snippet the one really hard to implement issue is GetHashCode().&amp;nbsp; The rules for GetHashCode() are both simple and seemingly contradictory&lt;/p&gt; &lt;ol&gt; &lt;li&gt;If two objects are equal (via Equals) their GetHashCode() should be equal&lt;/li&gt; &lt;li&gt;GetHashCode() shouldn't ever change &lt;/li&gt;&lt;/ol&gt; &lt;p&gt;These rules imply that GetHashCode() is related to Equality.&amp;nbsp; At a fundamental level though GetHashCode has nothing to do with Equality.&amp;nbsp; Instead it is linked to bucketing and ultimately any hashing sturcture such as Dictionary, Hashtable, etc ...&amp;nbsp; &lt;/p&gt; &lt;p&gt;Unfortunately it is impossible to separate these two from an API perspective because it is ingrained into the BCL.&amp;nbsp; There is a way to separate this out at a functionality level and still satisfy all of the rules of the GetHashCode() and Equals()&lt;/p&gt;&lt;pre class="code"&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Overrides&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function&lt;/span&gt; GetHashCode() &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Integer
&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;Return&lt;/span&gt; 1
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;This absolutely maintains both of the rules for GetHashCode().&amp;nbsp; This allows you to completely separate Equality and GetHashCode() in your implementation while not breaking any BCL rules or assumptions. &lt;/p&gt;
&lt;p&gt;Of course this does come with a trade off.&amp;nbsp; As said before GetHashCode() is primarily used as a bucketing mechanism.&amp;nbsp; It will cause the performance of bucketing collections such as Dictionary or Hashtable to drop from close to O(1) to O(N).&amp;nbsp; But once again this is not a bug but a conscious trade off.&amp;nbsp; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8569777" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Patterns/default.aspx">Patterns</category></item><item><title>Equality isn't easy</title><link>http://blogs.msdn.com/jaredpar/archive/2008/05/12/equality-isn-t-easy.aspx</link><pubDate>Mon, 12 May 2008 15:00:20 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8480384</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/8480384.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=8480384</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=8480384</wfw:comment><description>&lt;p&gt;After my recent postings on the &lt;a href="http://blogs.msdn.com/jaredpar/archive/2008/04/28/properly-implementing-equality-in-vb.aspx"&gt;rules of Equality&lt;/a&gt;, I thought it would be a good idea to post a simple example of equality.&amp;nbsp; The class in question, Example, has only one field of type Integer name m_field1.&amp;nbsp; Two instances of Example are equal if m_field1 has the same value.&amp;nbsp; So the real equality check is just a single Integer comparison.&amp;nbsp; &lt;/p&gt; &lt;p&gt;Unfortunately, as my posts alluded to, even though the check is simple getting it right is not necessarily so.&amp;nbsp; The equality portion of example takes roughly 20 lines of code while the actual equality check represents only 1 of those lines [1].&amp;nbsp; Not a good ratio.&amp;nbsp; The good and bad news about the other 19 lines is they are boiler plate so once you know them you don't have to think about them.&amp;nbsp; For my own purposes I've converted those 19 lines into a snippet which automates the process but doesn't make it any easier on the eye. &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;Class&lt;/span&gt; Example
    &lt;span style="color: rgb(0,0,255)"&gt;Implements&lt;/span&gt; IEquatable(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; Example)

    &lt;span style="color: rgb(0,0,255)"&gt;Private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;ReadOnly&lt;/span&gt; m_field1 &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Integer
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Sub&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;New&lt;/span&gt;(&lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; field &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Integer&lt;/span&gt;)
        m_field1 = field
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Sub

&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function&lt;/span&gt; Equals1(&lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; other &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; Example) &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Boolean&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Implements&lt;/span&gt; System.IEquatable(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; Example).Equals
        &lt;span style="color: rgb(0,0,255)"&gt;If&lt;/span&gt; other &lt;span style="color: rgb(0,0,255)"&gt;Is&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Nothing&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Then
&lt;/span&gt;            &lt;span style="color: rgb(0,0,255)"&gt;Return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;False
&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;If

&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;Return&lt;/span&gt; m_field1 = other.m_field1
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function

&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Overrides&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function&lt;/span&gt; Equals(&lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; obj &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Object&lt;/span&gt;) &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Boolean
&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;Return&lt;/span&gt; Equals1(&lt;span style="color: rgb(0,0,255)"&gt;TryCast&lt;/span&gt;(obj, Example))
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function

&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Overrides&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function&lt;/span&gt; GetHashCode() &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Integer
&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;Return&lt;/span&gt; m_field1.GetHashCode
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function

&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Shared&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Operator&lt;/span&gt; =(&lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; left &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; Example, &lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; right &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; Example) &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Boolean
&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;Return&lt;/span&gt; EqualityComparer(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; Example).Default.Equals(left, right)
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Operator

&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Shared&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Operator&lt;/span&gt; &amp;lt;&amp;gt;(&lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; left &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; Example, &lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; right &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; Example) &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Boolean
&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;Return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Not&lt;/span&gt; EqualityComparer(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; Example).Default.Equals(left, right)
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Operator

End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Class

Module&lt;/span&gt; Module1

    &lt;span style="color: rgb(0,0,255)"&gt;Sub&lt;/span&gt; AssertTrue(&lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; cond &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Boolean&lt;/span&gt;)
        Debug.Assert(cond, &lt;span style="color: rgb(163,21,21)"&gt;"failure"&lt;/span&gt;)
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Sub

&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Sub&lt;/span&gt; AssertFalse(&lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; cond &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Boolean&lt;/span&gt;)
        Debug.Assert(&lt;span style="color: rgb(0,0,255)"&gt;Not&lt;/span&gt; cond, &lt;span style="color: rgb(163,21,21)"&gt;"failure"&lt;/span&gt;)
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Sub

&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Sub&lt;/span&gt; Main()
        &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; v1 &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;New&lt;/span&gt; Example(1)
        &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; v2 &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;New&lt;/span&gt; Example(2)
        &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; v3 &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;New&lt;/span&gt; Example(1)

        AssertFalse(v1 &lt;span style="color: rgb(0,0,255)"&gt;Is&lt;/span&gt; v2)
        AssertFalse(v1 &lt;span style="color: rgb(0,0,255)"&gt;Is&lt;/span&gt; v3)
        AssertTrue(v1 &lt;span style="color: rgb(0,0,255)"&gt;Is&lt;/span&gt; v1)
        AssertFalse(v1 = v2)
        AssertTrue(v1 = v3)
        AssertFalse(v1 = &lt;span style="color: rgb(0,0,255)"&gt;Nothing&lt;/span&gt;)
        AssertFalse(&lt;span style="color: rgb(0,0,255)"&gt;Nothing&lt;/span&gt; = v1)
        AssertTrue(v1 &amp;lt;&amp;gt; v2)
        AssertTrue(v1 &amp;lt;&amp;gt; &lt;span style="color: rgb(0,0,255)"&gt;Nothing&lt;/span&gt;)
        AssertTrue(EqualityComparer(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; Example).Default.Equals(v1, v3))
        AssertFalse(EqualityComparer(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; Example).Default.Equals(v1, v2))
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Sub

End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Module
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;[1] Before VB criticism enters, C# has roughly the same ratio for the same sample.&amp;nbsp; &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8480384" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/VB/default.aspx">VB</category></item><item><title>IEquatable(Of T) and GetHashCode()</title><link>http://blogs.msdn.com/jaredpar/archive/2008/05/09/iequatable-of-t-and-gethashcode.aspx</link><pubDate>Fri, 09 May 2008 15:00:53 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8473844</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/8473844.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=8473844</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=8473844</wfw:comment><description>&lt;p&gt;This is a bit of a follow up to a &lt;a href="http://blogs.msdn.com/jaredpar/archive/2008/04/28/properly-implementing-equality-in-vb.aspx"&gt;previous post&lt;/a&gt; we discussed how to properly implement equality in VB.&amp;nbsp; Several users commented/asked that &lt;a href="http://msdn.microsoft.com/en-us/library/ms131187(VS.80).aspx"&gt;IEquatable(Of T)&lt;/a&gt; could be used in place of overriding Equals().&amp;nbsp; Since &lt;a href="http://msdn.microsoft.com/en-us/library/ms131187(VS.80).aspx"&gt;IEquatable(Of T)&lt;/a&gt;&amp;nbsp; doesn't define a GetHashCode() method the user didn't need to define it and hence run into all of the problems associated with GetHashCode() usage.&amp;nbsp; &lt;/p&gt; &lt;p&gt;Unfortunately this is not the case.&amp;nbsp; Several parts of the framework link IEquatable(Of T).Equals and Object.GetHashCode() in the same way that Object.Equals() and Object.GetHashCode() are linked. &lt;/p&gt; &lt;p&gt;The prime example of this is &lt;a href="http://msdn.microsoft.com/en-us/library/ms132123.aspx"&gt;EqualityComparer(Of T)&lt;/a&gt;.&amp;nbsp; This class is used to provide instances of IEqualityComparer(Of T) for any given type.&amp;nbsp; Under the hood it tries to determine the best way checking for equality in types.&amp;nbsp; If T implements IEquatable(Of T) it will eventually create an instance of GenericEqualityComparer(Of T) [1].&amp;nbsp; The methods of IEqualityComparer(Of T) are implemented as follows (boundary cases removed)&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Equals(left, right): return left.Equals(right) &lt;/li&gt; &lt;ul&gt; &lt;li&gt;Equals in this case is IEquatable(Of T).Equals&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;GetHashCode(obj): return obj.GetHashCode()&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;This implicitly links IEquatable(Of T).Equals to Object.GetHashCode().&amp;nbsp; Therefore if you implement IEquatable(Of T) you should also override GetHashCode().&amp;nbsp; The best way to view this is "if you implement IEquatable(Of T) you should override Equals and GetHashCode."&lt;/p&gt; &lt;p&gt;What's even more unfortunate is there is no feedback to indicate this relationship exists.&amp;nbsp; If you override Equals or GetHashCode both the C# and VB compilers will issue a warning/error.&amp;nbsp; Implementing IEquatable(Of T) produces no such warning.&amp;nbsp; &lt;/p&gt; &lt;p&gt;[1] Unfortunately this is a private type so you will need to use Reflector to view the type.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8473844" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Patterns/default.aspx">Patterns</category></item><item><title>Properly Implementing Equality in VB</title><link>http://blogs.msdn.com/jaredpar/archive/2008/04/28/properly-implementing-equality-in-vb.aspx</link><pubDate>Mon, 28 Apr 2008 15:04:06 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8428051</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/8428051.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=8428051</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=8428051</wfw:comment><description>&lt;p&gt;Many developers want to implement equality functions for their objects.&amp;#160; DotNet made equality a deep part of the framework and added support all the way up to System.Object with &lt;a href="http://msdn2.microsoft.com/en-us/library/bsc2ak47.aspx"&gt;Equals&lt;/a&gt; and &lt;a href="http://msdn2.microsoft.com/en-us/library/system.object.gethashcode.aspx"&gt;GetHashCode&lt;/a&gt;.&amp;#160;&amp;#160; In addition to the strongly enforced method semantics of GetHashCode and Equals there are also several other hard to enforce patterns that developers must follow in order to properly integrate into the rest of the DotNet framework.&amp;#160; We'll explore those rules today. &lt;/p&gt;  &lt;p&gt;Before even talking about how to implement equality we need to define the types of equality.&amp;#160; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Reference equality: Are these two objects really the exact same object.&amp;#160; &lt;/li&gt;    &lt;li&gt;Object/value equality: Depends on what the object author thinks equality means.&amp;#160; Can be anything from reference equality up to, comparing fields, to were they created in the same app domain. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In VB these are two very separate types of equality.&amp;#160; Reference equality is expressed through the &lt;a href="http://msdn2.microsoft.com/en-us/library/kb136x1y(VS.80).aspx"&gt;&amp;quot;Is&amp;quot;&lt;/a&gt; operator.&amp;#160; Object equality is done directly through operator=, operator&amp;lt;&amp;gt; and Equals.&amp;#160; This is also indirectly exposed via GetHashCode, EqualityComparer(Of T) and other framework patterns.&lt;/p&gt;  &lt;p&gt;When implementing object/value Equality there are four methods that are important to consider in order to fit expected patterns.&amp;#160; What's even more important is understanding which ones must be implemented together.&amp;#160; If an author overrides any of the functions in the following pairs they &lt;strong&gt;must &lt;/strong&gt;override both.&amp;#160; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Equals/GetHashCode&lt;/li&gt;    &lt;li&gt;Operator=/Operator!=&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;To make it easier, my rule of thumb is to override all four or none.&lt;/p&gt;  &lt;h3&gt;Equals&lt;/h3&gt;  &lt;p&gt;This is the bread and butter of object/value equality.&amp;#160; The author has free reign to decide what is and what is not equal.&amp;#160; However there are a few rules authors must follow in order to fit into the rest of the framework. &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Do not throw an exception from Equals.&amp;#160; Many components call Equals in a loop and there is no way for them to handle or recover from an exception.&amp;#160; If the object is not equal just return False &lt;/li&gt;    &lt;li&gt;The object passed in is typed to object.&amp;#160; It is perfectly valid for the framework to pass in an object that is completely unrelated to the type defining Equals.&amp;#160; The type author must account for and handle this case. &lt;/li&gt;    &lt;li&gt;The framework can pass in Nothing as a parameter to Equals and this is valid.&amp;#160; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;#2 and #3 may seem a bit off at first but it is implemented with a standard pattern as seen below. &lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Class &lt;/span&gt;C1
    &lt;span style="color: blue"&gt;Public Overrides Function &lt;/span&gt;Equals(&lt;span style="color: blue"&gt;ByVal &lt;/span&gt;obj &lt;span style="color: blue"&gt;As Object&lt;/span&gt;) &lt;span style="color: blue"&gt;As Boolean
        Dim &lt;/span&gt;other = &lt;span style="color: blue"&gt;TryCast&lt;/span&gt;(obj, C1)
        &lt;span style="color: blue"&gt;If &lt;/span&gt;other &lt;span style="color: blue"&gt;Is Nothing Then
            Return False
        End If
        &lt;/span&gt;...
    &lt;span style="color: blue"&gt;End Function
End Class&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;It's very important that you use &amp;quot;Is&amp;quot; to compare other in the above example.&amp;#160; Imagine if you slip up and type &amp;quot;=&amp;quot; instead.&amp;#160; You're about to override Operator= and this will cause &amp;quot;other=Nothing&amp;quot; to call operator=.&amp;#160; If this is a valid C1 instance operator= will almost certainly call Equals and then you'd have a stack overflow.&amp;#160; Our implementation of Operator= below will avoid this problem.&lt;/p&gt;

&lt;h3&gt;GetHashCode&lt;/h3&gt;

&lt;p&gt;This is both the easiest and trickiest function to override because it has very subtle semantics which cause very hard to find bugs in code.&amp;#160; The simple rule is &amp;quot;If two objects are equal in the sense of value equality they must return the same value in GetHashCode()&amp;quot;.&amp;#160; &lt;/p&gt;

&lt;p&gt;Why?&amp;#160; Many classes use the hash code to classify an object.&amp;#160; In particular hash tables and dictionaries tend to place objects in buckets based on their hash code.&amp;#160; When checking if an object is already in the hash table it will first look for it in a bucket.&amp;#160; If two objects are equal but have different hash codes they may be put into different buckets and the dictionary would fail to lookup the object.&lt;/p&gt;

&lt;p&gt;The better version of the GetHashCode rule has a small suffix on the simple rule.&amp;#160; &amp;quot;Only calculate the hash code based off of primitive fields which are ReadOnly&amp;quot;. This is not an absolute requirement as long as you are careful when you are code.&amp;#160; But as &lt;a href="http://blogs.msdn.com/jaredpar/archive/2008/03/24/part-of-being-a-good-programmer-is-learning-not-to-trust-yourself.aspx"&gt;previously stated&lt;/a&gt;, when coding it's best not to trust yourself to do the right thing.&amp;#160; Not doing this will get you into trouble when dealing with Hashtables and dictionaries.&amp;#160; &lt;/p&gt;

&lt;p&gt;For instance take this not so small example.&amp;#160; In this case value equality is based solely off of Field1 which is a modifiable field.&amp;#160; Once Field1 is changed you may or may not be able to access the value in the dictionary because GetHashCode() will change.&amp;#160; This example is contrived but it does happen in the real world and it can be incredibly difficult to track down.&amp;#160; &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Class &lt;/span&gt;C2
    &lt;span style="color: blue"&gt;Public &lt;/span&gt;Field1 &lt;span style="color: blue"&gt;As Integer

    Public Sub New&lt;/span&gt;(&lt;span style="color: blue"&gt;ByVal &lt;/span&gt;f1 &lt;span style="color: blue"&gt;As Integer&lt;/span&gt;)
        Field1 = f1
    &lt;span style="color: blue"&gt;End Sub
    Public Overrides Function &lt;/span&gt;GetHashCode() &lt;span style="color: blue"&gt;As Integer
        Return &lt;/span&gt;Field1.GetHashCode()
    &lt;span style="color: blue"&gt;End Function
    Public Overrides Function &lt;/span&gt;Equals(&lt;span style="color: blue"&gt;ByVal &lt;/span&gt;obj &lt;span style="color: blue"&gt;As Object&lt;/span&gt;) &lt;span style="color: blue"&gt;As Boolean
        Dim &lt;/span&gt;other = &lt;span style="color: blue"&gt;TryCast&lt;/span&gt;(obj, C2)
        &lt;span style="color: blue"&gt;If &lt;/span&gt;other &lt;span style="color: blue"&gt;Is Nothing Then
            Return False
        End If
        Return &lt;/span&gt;other.Field1 = Field1
    &lt;span style="color: blue"&gt;End Function
End Class

Module &lt;/span&gt;Module1

    &lt;span style="color: blue"&gt;Sub &lt;/span&gt;Main()
        &lt;span style="color: blue"&gt;Dim &lt;/span&gt;map = &lt;span style="color: blue"&gt;New &lt;/span&gt;Dictionary(&lt;span style="color: blue"&gt;Of &lt;/span&gt;C2, &lt;span style="color: blue"&gt;String&lt;/span&gt;)
        &lt;span style="color: blue"&gt;Dim &lt;/span&gt;v1 = &lt;span style="color: blue"&gt;New &lt;/span&gt;C2(44)
        map.Add(v1, &lt;span style="color: #a31515"&gt;&amp;quot;avalue&amp;quot;&lt;/span&gt;)
        Console.WriteLine(map(v1))
        v1.Field1 = 2
        Console.WriteLine(map(v1))  &lt;span style="color: green"&gt;' Potentially throws
    &lt;/span&gt;&lt;span style="color: blue"&gt;End Sub

End Module
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;If Field1 were ReadOnly there would be no way to hit this problem.&amp;#160; Then again we'd also not be able to change Field1.&amp;#160; &lt;/p&gt;

&lt;h3&gt;Operator=&lt;/h3&gt;

&lt;p&gt;When implementing equality overriding operator= allows you to use the more pleasant and reliable version of syntax comparison: a=b vs. a.Equals(b).&amp;#160; I say more reliable because using a.Equals(b) has an inherent dependency on &amp;quot;a&amp;quot; being a non-Nothing object.&amp;#160; &amp;quot;Operator=&amp;quot; makes no assumption and should operate correctly in the presence of Nothing.&lt;/p&gt;

&lt;p&gt;Operator= has virtually the same rules as Equals.&amp;#160; Mainly don't throw from operator=.&amp;#160; Operator= is usually just defined in terms of Equals() and since it also has to respect the no throw rule once we get there we are in good shape.&amp;#160; Getting to Equals() can be tricky though because one or both of the arguments can be Nothing.&amp;#160; In addition make sure not to use &amp;quot;=&amp;quot; to check for Nothing because you're back to the stack overflow problem.&amp;#160; &lt;/p&gt;

&lt;p&gt;What's great here is there is a simple solution that you should use every time you define Operator=.&amp;#160; &lt;a href="http://msdn2.microsoft.com/en-us/library/ms132123.aspx"&gt;EqualityComparer(Of T)&lt;/a&gt; knows all of these rules and in the face of both parameters being non-Nothing will call Equals() just like we want.&amp;#160; This makes the definition of Operator= boiler plate (I define very Operator= the exact same way)&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Public Shared Operator &lt;/span&gt;=(&lt;span style="color: blue"&gt;ByVal &lt;/span&gt;left &lt;span style="color: blue"&gt;As &lt;/span&gt;C2, &lt;span style="color: blue"&gt;ByVal &lt;/span&gt;right &lt;span style="color: blue"&gt;As &lt;/span&gt;C2) &lt;span style="color: blue"&gt;As Boolean
    Return &lt;/span&gt;EqualityComparer(&lt;span style="color: blue"&gt;Of &lt;/span&gt;C2).Default.Equals(left, right)
&lt;span style="color: blue"&gt;End Operator&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;What's even better is that EqualityComparer(Of T) understands the stack overflow problem which can occur in equality comparison and avoids it.&amp;#160; &lt;/p&gt;

&lt;h3&gt;Operator &amp;lt;&amp;gt;&lt;/h3&gt;

&lt;p&gt;Operator&amp;lt;&amp;gt; has the same rules as Operator= and luckily the same easy type of answer.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Public Shared Operator &lt;/span&gt;&amp;lt;&amp;gt;(&lt;span style="color: blue"&gt;ByVal &lt;/span&gt;left &lt;span style="color: blue"&gt;As &lt;/span&gt;C2, &lt;span style="color: blue"&gt;ByVal &lt;/span&gt;right &lt;span style="color: blue"&gt;As &lt;/span&gt;C2) &lt;span style="color: blue"&gt;As Boolean
    Return Not &lt;/span&gt;EqualityComparer(&lt;span style="color: blue"&gt;Of &lt;/span&gt;C2).Default.Equals(left, right)
&lt;span style="color: blue"&gt;End Operator&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;h3&gt;Wrapping Up&lt;/h3&gt;

&lt;p&gt;I started this article thinking it would be a few paragraphs of simple rules.&amp;#160; But as I kept going I kept remembering the subtleties and problems I encountered in the past.&amp;#160; &lt;/p&gt;

&lt;p&gt;For my own projects I avoid implementing equality unless it's truly needed because of the problems with properly implementing GetHashCode().&amp;#160; The one exception is when I define immutable objects.&amp;#160; Immutable objects have no problems with GetHashCode() since they are unchangable so Equality is straight forward.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8428051" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Patterns/default.aspx">Patterns</category></item><item><title>Me, MyBase, MyClass and MyPost on the subject</title><link>http://blogs.msdn.com/jaredpar/archive/2008/04/25/me-mybase-myclass-and-mypost-on-the-subject.aspx</link><pubDate>Fri, 25 Apr 2008 18:09:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8424213</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/8424213.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=8424213</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=8424213</wfw:comment><description>&lt;p&gt;Recently we had a good discussion on an internal alias about the use of Me, MyClass and MyBase in VB.&amp;nbsp; Me, MyBase and MyClass are all ways to access instance member data in a VB class or structure.&amp;nbsp; There was a little bit of confusion on the actual workings and meanings of the keywords in various contexts and I want to use this post to shed light on the different meanings. &lt;/p&gt; &lt;h3&gt;The Basics&lt;/h3&gt; &lt;p&gt;The keywords are used to alter the way in which instance members of a class/structure are accessed.&amp;nbsp; In particular they affect the way Overridable/MustOverride/Overrides functions are evaluated. Methods defined with Overridable/Overrides/MustOverride are defined as virtual by the CLR.&amp;nbsp; For the purpose of this post all of these definitions are mostly equal.&amp;nbsp; This discussion will be useless without and example so here's the code to discuss.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Class &lt;/span&gt;GrandParent
    &lt;span style="color: blue"&gt;Public Overridable Sub &lt;/span&gt;Sub1()
        Console.WriteLine(&lt;span style="color: #a31515"&gt;"GrandParent.Sub1"&lt;/span&gt;)
    &lt;span style="color: blue"&gt;End Sub
End Class

Class &lt;/span&gt;Parent
    &lt;span style="color: blue"&gt;Inherits &lt;/span&gt;GrandParent
    &lt;span style="color: blue"&gt;Public Overrides Sub &lt;/span&gt;Sub1()
        Console.WriteLine(&lt;span style="color: #a31515"&gt;"Parent.Sub1"&lt;/span&gt;)
    &lt;span style="color: blue"&gt;End Sub
End Class

Class &lt;/span&gt;Child
    &lt;span style="color: blue"&gt;Inherits &lt;/span&gt;Parent
    &lt;span style="color: blue"&gt;Public Overrides Sub &lt;/span&gt;Sub1()
        Console.WriteLine(&lt;span style="color: #a31515"&gt;"Child.Sub1"&lt;/span&gt;)
    &lt;span style="color: blue"&gt;End Sub
End Class&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;In this case Sub1 is a virtual method and there are three instances of it (one per class).&amp;nbsp; By default virtual methods are called based on the runtime type of the object.&amp;nbsp; The CLR will essentially walk the hierarchy from current type to object looking for the first class which defines a particular method and call that version.&amp;nbsp; It doesn't matter what the variable type is declared as, just what type it actually is.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Dim &lt;/span&gt;v1 &lt;span style="color: blue"&gt;As &lt;/span&gt;GrandParent = &lt;span style="color: blue"&gt;New &lt;/span&gt;Parent
v1.Sub1()   &lt;span style="color: green"&gt;' Calls Parent.Sub1
&lt;/span&gt;&lt;span style="color: blue"&gt;Dim &lt;/span&gt;v2 &lt;span style="color: blue"&gt;As &lt;/span&gt;GrandParent = &lt;span style="color: blue"&gt;New &lt;/span&gt;GrandParent
v2.Sub1()   &lt;span style="color: green"&gt;' Calls GrandParent.Sub1&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;h3&gt;Changing the call&lt;/h3&gt;
&lt;p&gt;If the CLR will always call a virtual Sub/Function based on the runtime type of an object how can I access the parent function?&amp;nbsp; This is where MyBase comes in.&amp;nbsp; MyBase allows you to call the version of the virtual method defined in the parent class.&amp;nbsp; Essentially it tells the CLR call this method/property as if my runtime type was my base type.&amp;nbsp; &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Class &lt;/span&gt;Child2
    &lt;span style="color: blue"&gt;Inherits &lt;/span&gt;Parent
    &lt;span style="color: blue"&gt;Public Overrides Sub &lt;/span&gt;Sub1()
        &lt;span style="color: blue"&gt;MyBase&lt;/span&gt;.Sub1()   &lt;span style="color: green"&gt;' Calls Parent.Sub1
        &lt;/span&gt;Console.WriteLine(&lt;span style="color: #a31515"&gt;"Child2.Sub1"&lt;/span&gt;)
    &lt;span style="color: blue"&gt;End Sub
End Class
&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;MyClass is similar to MyBase.&amp;nbsp; Instead of telling the CLR the current type is the base type, it tells the CLR the runtime type is the type where MyClass is used.&amp;nbsp; This allows developers to call their type's version of a virtual method no matter who derives from them.&amp;nbsp; In the following example it doesn't matter how many, or who derives from Child3, Sub2 will always call the version of Sub1 defined in Child3.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Class &lt;/span&gt;Child3
    &lt;span style="color: blue"&gt;Inherits &lt;/span&gt;Parent
    &lt;span style="color: blue"&gt;Public Overrides Sub &lt;/span&gt;Sub1()
        Console.WriteLine(&lt;span style="color: #a31515"&gt;"Child3.Sub1"&lt;/span&gt;)
    &lt;span style="color: blue"&gt;End Sub
    Public Sub &lt;/span&gt;Sub2()
        &lt;span style="color: blue"&gt;MyClass&lt;/span&gt;.Sub1()
    &lt;span style="color: blue"&gt;End Sub
End Class&lt;/span&gt;&lt;/pre&gt;
&lt;h3&gt;So, why not MyChild?&lt;/h3&gt;
&lt;p&gt;The short answer is, it's not verifiable.&amp;nbsp; When writing MyBase we can verify that indeed there is a sub/function/property matching the call site in the base class.&amp;nbsp; If no such method exists it will result in an error.&amp;nbsp; MyClass is similarly easy to verify.&amp;nbsp; With MyChild however there would be no useful way of guaranteeing a particular sub/function/property was defined on the child class.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;One way you can verify a child class contains a particular property/sub/function is to make it MustOverride.&amp;nbsp; However in this case there is no actual definition in the original type.&amp;nbsp; In fact, if you try and access a MustOverride method with MyClass it will generate a compile time error. Therefore every call must at least occur in the child class or lower rendering MyChild superfluous.&lt;/p&gt;
&lt;h3&gt;What about non-virtual methods and properties?&lt;/h3&gt;
&lt;p&gt;The primary intent of MyBase/MyClass is to call virtual methods in a non-virtual way.&amp;nbsp; However they can also be used to call non-virtual methods.&amp;nbsp; From the perspective of the user calling a non-virtual method with MyBase/MyClass/Me has no discernable difference.&amp;nbsp; If you crack open the generated IL you can see a small difference in the op code but the short story is it won't affect your program.&amp;nbsp; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8424213" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/VB/default.aspx">VB</category></item><item><title>BinaryInsert Part2</title><link>http://blogs.msdn.com/jaredpar/archive/2008/04/07/binaryinsert-part2.aspx</link><pubDate>Mon, 07 Apr 2008 22:09:36 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8349083</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/8349083.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=8349083</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=8349083</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/jaredpar/archive/2008/03/31/missing-api-list-of-t-binaryinsert.aspx"&gt;Previously&lt;/a&gt; I discussed a potential missing API in List(Of T).BinaryInsert.&amp;nbsp; One of the items I mentioned was it had better performance because it was O(Log N) vs Insert and Sort which is O(NLogN).&amp;nbsp; Several users correctly pointed out this was incorrect and that Insert() had the additional overhead of an Array.Copy() which is O(N)ish.&amp;nbsp; But most agreed O(N) + O(LogN) was better than O(NLogN).&amp;nbsp; &lt;/p&gt; &lt;p&gt;Given that I already missed a key portion, I decided to write a test program to try out the various methods.&amp;nbsp; Caveat: I'm not a performance guy.&amp;nbsp; While I find performance intriguing and interesting it is by no means my specialty.&amp;nbsp; Any single performance test is unlikely to capture all real world scenarios.&amp;nbsp; However I did find the results a bit surprising.&amp;nbsp; At the bottom of the post is the test code I wrote.&amp;nbsp; &lt;/p&gt; &lt;p&gt;Here is the summary output.&amp;nbsp; &lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Force Jit&lt;br&gt;BinaryInsert:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 00:00:00.0051167&lt;br&gt;Insert Then Sort: 00:00:00.0000251&lt;br&gt;Range (0-99)&lt;br&gt;BinaryInsert:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 00:00:00.0000266&lt;br&gt;Insert Then Sort: 00:00:00.0000316&lt;br&gt;Random 10&lt;br&gt;BinaryInsert:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 00:00:00.0000053&lt;br&gt;Insert Then Sort: 00:00:00.0000034&lt;br&gt;Random 100&lt;br&gt;BinaryInsert:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 00:00:00.0000294&lt;br&gt;Insert Then Sort: 00:00:00.0000235&lt;br&gt;Random 1000&lt;br&gt;BinaryInsert:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 00:00:00.0004917&lt;br&gt;Insert Then Sort: 00:00:00.0001526&lt;br&gt;Random 10000&lt;br&gt;BinaryInsert:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 00:00:00.0261899&lt;br&gt;Insert Then Sort: 00:00:00.0018287&lt;br&gt;Random 100000&lt;br&gt;BinaryInsert:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 00:00:02.4289054&lt;br&gt;Insert Then Sort: 00:00:00.0237019&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;As you can see, based on my sample program, BinaryInsert is much slower than Insert and Sort.&amp;nbsp; I ran the profiler against this and verified the suspicion that List(Of T).Insert() took the vast majority of the time.&amp;nbsp; &lt;p&gt;Perhaps there is a reason BinaryInsert is missing. &lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;Module&lt;/span&gt; Module1

    &lt;span style="color: rgb(0,0,255)"&gt;Function&lt;/span&gt; BinaryInsert(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T)(&lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; enumerable &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; IEnumerable(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T), &lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; comp &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; IComparer(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T)) &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; TimeSpan
        &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; list &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;New&lt;/span&gt; List(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T)
        &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; watch &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;New&lt;/span&gt; Stopwatch()

        watch.Start()
        &lt;span style="color: rgb(0,0,255)"&gt;For&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Each&lt;/span&gt; value &lt;span style="color: rgb(0,0,255)"&gt;In&lt;/span&gt; enumerable
            list.BinaryInsert(value, comp)
        &lt;span style="color: rgb(0,0,255)"&gt;Next
&lt;/span&gt;        watch.Stop()
        &lt;span style="color: rgb(0,0,255)"&gt;Return&lt;/span&gt; watch.Elapsed
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function

&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Function&lt;/span&gt; InsertAllThenSort(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T)(&lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; enumerable &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; IEnumerable(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T), &lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; comp &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; IComparer(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T)) &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; TimeSpan
        &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; list &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;New&lt;/span&gt; List(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T)
        &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; watch &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;New&lt;/span&gt; Stopwatch()

        watch.Start()
        &lt;span style="color: rgb(0,0,255)"&gt;For&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Each&lt;/span&gt; value &lt;span style="color: rgb(0,0,255)"&gt;In&lt;/span&gt; enumerable
            list.Add(value)
        &lt;span style="color: rgb(0,0,255)"&gt;Next
&lt;/span&gt;        list.Sort(comp)
        watch.Stop()
        &lt;span style="color: rgb(0,0,255)"&gt;Return&lt;/span&gt; watch.Elapsed
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function

&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Sub&lt;/span&gt; TestBoth(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T)(&lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; title &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;String&lt;/span&gt;, &lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; enumerable &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; IEnumerable(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T))
        TestBoth(title, enumerable, Comparer(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T).Default)
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Sub

&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Sub&lt;/span&gt; TestBoth(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T)(&lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; title &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;String&lt;/span&gt;, &lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; enumerable &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; IEnumerable(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T), &lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; comp &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; IComparer(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T))
        &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; copy = &lt;span style="color: rgb(0,0,255)"&gt;New&lt;/span&gt; List(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T)(enumerable)
        &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; ellapsedBinary = BinaryInsert(&lt;span style="color: rgb(0,0,255)"&gt;New&lt;/span&gt; List(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T)(copy), comp)
        &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; ellapsedSort = InsertAllThenSort(&lt;span style="color: rgb(0,0,255)"&gt;New&lt;/span&gt; List(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T)(copy), comp)

        Console.WriteLine(title)
        Console.WriteLine(&lt;span style="color: rgb(163,21,21)"&gt;"BinaryInsert:     {0}"&lt;/span&gt;, ellapsedBinary)
        Console.WriteLine(&lt;span style="color: rgb(163,21,21)"&gt;"Insert Then Sort: {0}"&lt;/span&gt;, ellapsedSort)
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Sub

&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Function&lt;/span&gt; Range(&lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; start &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Integer&lt;/span&gt;, &lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; count &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Integer&lt;/span&gt;) &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; List(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Integer&lt;/span&gt;)
        &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; list = &lt;span style="color: rgb(0,0,255)"&gt;New&lt;/span&gt; List(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Integer&lt;/span&gt;)
        &lt;span style="color: rgb(0,0,255)"&gt;For&lt;/span&gt; i = start &lt;span style="color: rgb(0,0,255)"&gt;To&lt;/span&gt; count - 1
            list.Add(i)
        &lt;span style="color: rgb(0,0,255)"&gt;Next
&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;Return&lt;/span&gt; list
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function

&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Function&lt;/span&gt; Random(&lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; count &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Integer&lt;/span&gt;) &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; List(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Integer&lt;/span&gt;)
        &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; rand &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;New&lt;/span&gt; Random()
        &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; list = &lt;span style="color: rgb(0,0,255)"&gt;New&lt;/span&gt; List(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Integer&lt;/span&gt;)
        &lt;span style="color: rgb(0,0,255)"&gt;For&lt;/span&gt; i = 0 &lt;span style="color: rgb(0,0,255)"&gt;To&lt;/span&gt; count - 1
            list.Add(rand.Next())
        &lt;span style="color: rgb(0,0,255)"&gt;Next
&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;Return&lt;/span&gt; list
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function

&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Sub&lt;/span&gt; Main()
        TestBoth(&lt;span style="color: rgb(163,21,21)"&gt;"Force Jit"&lt;/span&gt;, &lt;span style="color: rgb(0,0,255)"&gt;New&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Integer&lt;/span&gt;() {1})
        TestBoth(&lt;span style="color: rgb(163,21,21)"&gt;"Range (0-99)"&lt;/span&gt;, Range(0, 100))
        TestBoth(&lt;span style="color: rgb(163,21,21)"&gt;"Random 10"&lt;/span&gt;, Random(10))
        TestBoth(&lt;span style="color: rgb(163,21,21)"&gt;"Random 100"&lt;/span&gt;, Random(100))
        TestBoth(&lt;span style="color: rgb(163,21,21)"&gt;"Random 1000"&lt;/span&gt;, Random(1000))
        TestBoth(&lt;span style="color: rgb(163,21,21)"&gt;"Random 10000"&lt;/span&gt;, Random(10000))
        TestBoth(&lt;span style="color: rgb(163,21,21)"&gt;"Random 100000"&lt;/span&gt;, Random(100000))
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Sub

End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Module&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8349083" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/VB/default.aspx">VB</category></item><item><title>Have a IComparable(Of T) but need an IComparer(Of T)?</title><link>http://blogs.msdn.com/jaredpar/archive/2008/04/02/have-a-icomparable-of-t-but-need-an-icomparer-of-t.aspx</link><pubDate>Thu, 03 Apr 2008 04:33:52 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8344484</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/8344484.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=8344484</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=8344484</wfw:comment><description>&lt;p&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/4d7sx9hd.aspx"&gt;IComparable(Of T)&lt;/a&gt; is an interface saying &amp;quot;I can compare myself to other objects of the same type&amp;quot;.&amp;#160; And &lt;a href="http://msdn2.microsoft.com/en-us/library/8ehhxeaf.aspx"&gt;IComparer(Of T)&lt;/a&gt; is an interface saying &amp;quot;I can compare two objects of this type.&amp;quot;.&amp;#160; Often API's which need to perform comparisons will take an instance of IComparer(Of T) instead of IComparable(Of T).&amp;#160; &lt;/p&gt;  &lt;p&gt;Doing the opposite is limiting in a few ways.&amp;#160; The first is it locks developers into the behavior defined by the type author essentially preventing them from deciding to compare in a different way.&amp;#160; The second is if the type author didn't didn't implement IComparable(Of T), we must define a wrapper class that does.&amp;#160; This is even more awkward because collections now contain instances of the wrapper.&amp;#160; Also there is one wrapper overhead per instance in the collection.&amp;#160; &lt;/p&gt;  &lt;p&gt;Now back to the original problem, we have a type which implements IComparable(Of T) but don't have an IComparer(Of T) wrapper class.&amp;#160; Luckily the .Net Framework provides a solution.&amp;#160; Comparer(Of T).Default.&amp;#160; It provides a quick IComparer(Of T) wrapper that automatically delegates to IComparable(Of T) if the type defines it.&amp;#160; &lt;/p&gt;  &lt;p&gt;Example usage:&amp;#160; &lt;a href="http://blogs.msdn.com/jaredpar/archive/2008/03/31/missing-api-list-of-t-binaryinsert.aspx"&gt;Previously&lt;/a&gt; we defined a BinaryInsert method for List(Of T).&amp;#160; It required an explicit IComparer(Of T) be passed even for simple types like Int32.&amp;#160; We can fix this by using the Comparer(Of T) class.&amp;#160; &lt;/p&gt;  &lt;pre class="code"&gt;    &amp;lt;Extension()&amp;gt; _
    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Sub&lt;/span&gt; BinaryInsert(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T)(&lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; list &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; List(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T), &lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; value &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; T)
        list.BinaryInsert(value, Comparer(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T).Default)
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Sub&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8344484" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Patterns/default.aspx">Patterns</category></item><item><title>Missing API: List(Of T).BinaryInsert</title><link>http://blogs.msdn.com/jaredpar/archive/2008/03/31/missing-api-list-of-t-binaryinsert.aspx</link><pubDate>Mon, 31 Mar 2008 17:26:42 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8344445</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/8344445.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=8344445</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=8344445</wfw:comment><description>&lt;p&gt;One API that seems to be missing from &lt;a href="http://msdn2.microsoft.com/en-us/library/6sh2ey19.aspx"&gt;List(Of T)&lt;/a&gt; is a BinaryInsert method.&amp;#160; Especially since there is already a &lt;a href="http://msdn2.microsoft.com/en-us/library/3f90y839.aspx"&gt;BinarySearch&lt;/a&gt; method. &lt;/p&gt;  &lt;p&gt;Binary insert is a method for inserting a value into an already sorted list.&amp;#160; Since the list is already sorted we can do a binary search to find the appropriate place to insert.&amp;#160; The insert keeps the list sorted so the cost of a binary insert is just the cost of the search which is O(Log(N)).&amp;#160; &lt;/p&gt;  &lt;p&gt;An alternative method for keeping a sorted list sorted is to insert and then resort.&amp;#160; Most sorting algorithms have a cost of O(N*Log(N)).&amp;#160; In other words it's N times more expensive. &lt;/p&gt;  &lt;p&gt;Yet this API doesn't exist.&amp;#160; No matter.&amp;#160; We can quickly fix this problem with a couple of extension methods.&amp;#160; &lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Module&lt;/span&gt; Extensions

    &amp;lt;Extension()&amp;gt; _
    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Sub&lt;/span&gt; BinaryInsert(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T)(&lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; list &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; List(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T), &lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; value &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; T, &lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; comp &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; IComparer(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T))
        list.BinaryInsert(value, comp, 0, list.Count)
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Sub

&lt;/span&gt;    &amp;lt;Extension()&amp;gt; _
    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Sub&lt;/span&gt; BinaryInsert(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T)(&lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; list &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; List(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T), _
                                  &lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; value &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; T, _
                                  &lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; comparer &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; IComparer(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T), _
                                  &lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; iStart &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Integer&lt;/span&gt;, _
                                  &lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; iEnd &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Integer&lt;/span&gt;)
        &lt;span style="color: rgb(0,0,255)"&gt;While&lt;/span&gt; iStart &amp;lt; iEnd
            &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; len = iEnd - iStart
            &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; iMiddle = iStart + (len \ 2)
            &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; comp = comparer.Compare(value, list(iMiddle))
            &lt;span style="color: rgb(0,0,255)"&gt;If&lt;/span&gt; 0 = comp &lt;span style="color: rgb(0,0,255)"&gt;Then
&lt;/span&gt;                iStart = iMiddle
                &lt;span style="color: rgb(0,0,255)"&gt;Exit&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;While
&lt;/span&gt;            &lt;span style="color: rgb(0,0,255)"&gt;ElseIf&lt;/span&gt; comp &amp;lt; 0 &lt;span style="color: rgb(0,0,255)"&gt;Then
&lt;/span&gt;                iEnd = iMiddle
            &lt;span style="color: rgb(0,0,255)"&gt;Else
&lt;/span&gt;                iStart = iMiddle + (len &lt;span style="color: rgb(0,0,255)"&gt;Mod&lt;/span&gt; 2)
            &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;If
&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;While
&lt;/span&gt;        list.Insert(iStart, value)
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Sub

End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Module&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8344445" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Patterns/default.aspx">Patterns</category></item></channel></rss>