<?xml-stylesheet type="text/xsl" href="/rss.xsl" media="screen"?><rss version="2.0"><channel><title>softlogger Latest Articles ::Object-Oriented-Concepts</title><link>http://softlogger.com</link><description>softlogger Latest Articles ::Object-Oriented-Concepts</description><ttl>180</ttl><item><title>What's wrong with one of GetNumberFormat's callers? And what's wrong with GetNumberFormat?</title><link>http://softlogger.com/20344/Object-Oriented-Concepts/what-s-wrong-with-one-of-getnumberformat-s-callers-and-what-s-wrong-with-getnumberformat.aspx</link><description>&lt;P&gt;&lt;FONT color=#ff0000 size=1&gt;&lt;EM&gt;Please read the &lt;/EM&gt;&lt;/FONT&gt;&lt;A class=" " href="http://blogs.msdn.com/michkap/pages/7934999.aspx" mce_href="http://blogs.msdn.com/michkap/pages/7934999.aspx"&gt;&lt;EM&gt;&lt;FONT size=1&gt;disclaimer&lt;/FONT&gt;&lt;/EM&gt;&lt;/A&gt;&lt;EM&gt;&lt;FONT color=#ff0000 size=1&gt;; content of &lt;A class=" " href="http://blogs.msdn.com/michkap" mce_href="http://blogs.msdn.com/michkap"&gt;Michael Kaplan's blog&lt;/A&gt; not approved by Microsoft!&lt;/FONT&gt;&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;Some of you may recall Igor Levicki, the guy who had 64-bit keyboards working before MSKLC 1.4 was released who I mentioned in &lt;A class=" " href="http://blogs.msdn.com/michkap/archive/2006/09/28/774957.aspx" mce_href="http://blogs.msdn.com/michkap/archive/2006/09/28/774957.aspx"&gt;&lt;STRONG&gt;If you just don't think you can hold it (64-bit style!)&lt;/STRONG&gt;&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;The other day he sent me mail about a bug (actually a small bundle of bugs, but the bug he found was a crash bug) in a third party application (name withheld to protect the guilty, and&amp;nbsp;also the embarrassed!).&lt;/P&gt;
&lt;P&gt;Igor&amp;nbsp;looked at crash via the disassembly, which I'll put here just for the sake of completeness. If you are the same kind of person you can work along here and try to find the problems within the disassembly:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Consolas,Lucida Console,Courier New,Courier,fixed" size=1&gt;; Exported entry 592. &lt;A href="mailto:?GetDoubleFormat@CAppUtils@@SAPB_WNH@Z"&gt;?GetDoubleFormat@CAppUtils@@SAPB_WNH@Z&lt;/A&gt;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Consolas,Lucida Console,Courier New,Courier,fixed" size=1&gt;; wchar_t* __cdecl CAppUtils__GetDoubleFormat(double, int)&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Consolas,Lucida Console,Courier New,Courier,fixed" size=1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public &lt;A href="mailto:?GetDoubleFormat@CAppUtils@@SAPB_WNH@Z"&gt;?GetDoubleFormat@CAppUtils@@SAPB_WNH@Z&lt;/A&gt;&amp;nbsp;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Consolas,Lucida Console,Courier New,Courier,fixed" size=1&gt;&lt;A href="mailto:?GetDoubleFormat@CAppUtils@@SAPB_WNH@Z"&gt;?GetDoubleFormat@CAppUtils@@SAPB_WNH@Z&lt;/A&gt; proc near&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Consolas,Lucida Console,Courier New,Courier,fixed" size=1&gt;var_108&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = qword&amp;nbsp;&amp;nbsp;&amp;nbsp; ptr -108h&lt;BR&gt;LCData&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = word ptr -0D4h&lt;BR&gt;Value&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = word ptr -0D0h&lt;BR&gt;var_4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = dword&amp;nbsp;&amp;nbsp;&amp;nbsp; ptr -4&lt;BR&gt;arg_0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = qword&amp;nbsp;&amp;nbsp;&amp;nbsp; ptr&amp;nbsp; 8&lt;BR&gt;arg_8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = dword&amp;nbsp;&amp;nbsp;&amp;nbsp; ptr&amp;nbsp; 10h&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Consolas,Lucida Console,Courier New,Courier,fixed" size=1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; ebp&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp; ebp, esp&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; and&amp;nbsp;&amp;nbsp;&amp;nbsp; esp, 0FFFFFFC0h&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sub&amp;nbsp;&amp;nbsp;&amp;nbsp; esp, 0FCh&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, dword_1007E01C&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xor&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, esp&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp; [esp+0FCh+var_4], eax&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Consolas,Lucida Console,Courier New,Courier,fixed" size=1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fld&amp;nbsp;&amp;nbsp;&amp;nbsp; [ebp+arg_0]&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; esi&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sub&amp;nbsp;&amp;nbsp;&amp;nbsp; esp, 8&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fstp&amp;nbsp;&amp;nbsp;&amp;nbsp; [esp+108h+var_108]&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lea&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, [esp+108h+Value]&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; offset aF&amp;nbsp;&amp;nbsp;&amp;nbsp; ; "%f"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; eax&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; String&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp; ds:_swprintf&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; add&amp;nbsp;&amp;nbsp;&amp;nbsp; esp, 10h&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Consolas,Lucida Console,Courier New,Courier,fixed" size=1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; 0FFh&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; cchNumber&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; offset word_100873B0 ; lpNumberStr&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; lpFormat&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lea&amp;nbsp;&amp;nbsp;&amp;nbsp; ecx, [esp+10Ch+Value]&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; ecx&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; lpValue&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; dwFlags&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; 400h&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; Locale&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp; ds:GetNumberFormatW&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Consolas,Lucida Console,Courier New,Courier,fixed" size=1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; 2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; cchData&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lea&amp;nbsp;&amp;nbsp;&amp;nbsp; edx, [esp+104h+LCData]&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; edx&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; lpLCData&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; 0Eh&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; LCType&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; 400h&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; Locale&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp; ds:GetLocaleInfoW&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Consolas,Lucida Console,Courier New,Courier,fixed" size=1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp; esi, [ebp+arg_8]&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cmp&amp;nbsp;&amp;nbsp;&amp;nbsp; esi, 0FFFFFFFFh&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; jz&amp;nbsp;&amp;nbsp;&amp;nbsp; short loc_10008344&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, dword ptr [esp+100h+LCData]&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; eax&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; Ch&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; offset word_100873B0 ; Str&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp; ds:wcsrchr&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; add&amp;nbsp;&amp;nbsp;&amp;nbsp; esp, 8&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Consolas,Lucida Console,Courier New,Courier,fixed" size=1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; test&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, eax&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; jz&amp;nbsp;&amp;nbsp;&amp;nbsp; short loc_1000833F&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lea&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, [eax+esi*2+2]&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Consolas,Lucida Console,Courier New,Courier,fixed" size=1&gt;loc_1000833F:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp; word ptr [eax],&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Consolas,Lucida Console,Courier New,Courier,fixed" size=1&gt;loc_10008344:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp; ecx, [esp+100h+var_4]&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pop&amp;nbsp;&amp;nbsp;&amp;nbsp; esi&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xor&amp;nbsp;&amp;nbsp;&amp;nbsp; ecx, esp&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Consolas,Lucida Console,Courier New,Courier,fixed" size=1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, offset word_100873B0&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Consolas,Lucida Console,Courier New,Courier,fixed" size=1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp; sub_10059B35&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp; esp, ebp&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pop&amp;nbsp;&amp;nbsp;&amp;nbsp; ebp&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; retn&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Consolas,Lucida Console,Courier New,Courier,fixed" size=1&gt;&lt;A href="mailto:?GetDoubleFormat@CAppUtils@@SAPB_WNH@Z"&gt;?GetDoubleFormat@CAppUtils@@SAPB_WNH@Z&lt;/A&gt; endp&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;From assembly it is pretty hard to know whose application it is, but what is happening in this one function is not too hard to figure out.&lt;/P&gt;
&lt;P mce_keep="true"&gt;Now for those who really aren't as comfortable working&amp;nbsp;this way where you have watch&amp;nbsp;parameters get placed on the stack an such&amp;nbsp;(though it should be fairly straightforward to work with&amp;nbsp;in this case&amp;nbsp;for those so inclined!), here is some essentially equivalent&amp;nbsp;C code:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;BLOCKQUOTE&gt;&lt;FONT face="Consolas,Lucida Console,Courier New,Courier,fixed"&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;wchar_t Formatted[256];&lt;BR&gt;&lt;BR&gt;wchar_t *GetDoubleFormat(double Value, int DecimalPlaces) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; wchar_t Buffer[MAX_PATH];&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DecimalChar;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _swprintf(Buffer, "%f", Value);&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GetNumberFormatW(LOCALE_USER_DEFAULT, LOCALE_NOUSEROVERRIDE, Buffer, NULL, Formatted, 255);&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, &amp;amp;DecimalChar, 2);&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (DecimalPlaces != -1) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; wchar_t *Point = wcsrchr(Formatted, DecimalChar);&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (Point != NULL) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Point = Point + DecimalPlaces + 1;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *Point = 0x0000;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return Formatted;&lt;BR&gt;}&lt;/STRONG&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/BLOCKQUOTE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;Now this bit of code is as veritable bug farm of how to misuse the NLS API.&lt;/P&gt;
&lt;P mce_keep="true"&gt;What it is trying to do, with many of the bugs embedded in the descriptive language for easy retrieval:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Format a passed in double with the current user default locale and allowing no user overrides.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Retrieve the numeric decimal separator,&amp;nbsp;allowing user overrides.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Search backward through the formatted string looking for that decimal separator.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Increment the pointer to be the passed in number of places after the decimal separator plus one.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Stick a NULL there, effectively truncated the formatted string there.&lt;/DIV&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P mce_keep="true"&gt;Originally Igor was thinking this might have even made a great entry for &lt;A class=" " href="http://thedailywtf.com/" mce_href="http://thedailywtf.com/"&gt;The Daily WTF&lt;/A&gt;, and I'm not gonna disagree with him on that.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;EM&gt;The crash bug&amp;nbsp;Igor had run into initially was based on the fact that he had Serbian locale settings with a customized decimal separator -- thus the user override mismatch in #1 and #2 above quickly led to a problem searching for a "." in a string such as "44,90" -- then after properly detecting that wcsrchr returning NULL for failure, a somewhat catastrophic situation arises when it tries to dereference that NULL in order to assign to it.&lt;/EM&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Basically what they (apparently) wanted to do was format a number with the user's preferences but overriding the user's choice of the number of decimal places. The resulting string is&amp;nbsp;put in their user interface, returning the result to the user in a property sheet.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;FONT color=#009933 size=4&gt;Worse&amp;nbsp;ways of&amp;nbsp;achieving that goal&amp;nbsp;have been&amp;nbsp;reported in code reviews, but not by reliable witnesses.&lt;/FONT&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;(There are other silly/problematic issues here, such as:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;LOCALE_SDECIMAL can be up to two characters; this code assumes it is always one (note that this is a problem most code&amp;nbsp;tends to&amp;nbsp;have)&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;The retrieved LOCALE_SDECIMAL value is stored in an &amp;amp;int, presumably to facilitate the later wcsrchr call, but which is less than ideal always (and in the case of #1 will guarantee incorrect detection behavior);&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;GetNumberFormatW assumes that space for the NULL is included in the buffer -- why allocate a wchar_t array of 256 if you are only going to pass 255 for the length? If the function cannot fit the NULL it will fail;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;No return value checking for _swprintf, GetNumberFormatW or GetLocaleInfoW -- despite the fact that they can all return errors and some of the errors would have negative side effects on the intended operation of&amp;nbsp;their GetDoubleFormat function.&lt;/DIV&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P mce_keep="true"&gt;Now in fairness to the people who wrote this code (whoever they are and whenever they wrote it), &lt;A class=" " href="http://msdn2.microsoft.com/library/ms776317.aspx" mce_href="http://msdn2.microsoft.com/library/ms776317.aspx"&gt;GetNumberFormat&lt;/A&gt; has some specific limitations that make it less useful and that make it more difficult to&amp;nbsp;write the idealized version of this function.&lt;/P&gt;
&lt;P mce_keep="true"&gt;I am going to enumerate the&amp;nbsp;three big problems&amp;nbsp;here as I see them, and Igor might have some additional thoughts on this matter either for comments here or on &lt;A class=" " href="http://www.levicki.net/" mce_href="http://www.levicki.net"&gt;his own site&lt;/A&gt;. :-)&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;FONT color=#ff0000&gt;&lt;STRONG&gt;But the NLS team could think of this next bit as feedback to them&lt;/STRONG&gt;&lt;/FONT&gt; on ways to make functions like &lt;A class=" " href="http://msdn2.microsoft.com/library/ms776317.aspx" mce_href="http://msdn2.microsoft.com/library/ms776317.aspx"&gt;GetNumberFormat&lt;/A&gt; better, faster, easier to use, and more generally useful.&lt;/P&gt;
&lt;P mce_keep="true"&gt;First of all,&amp;nbsp;since &lt;A class=" " href="http://msdn2.microsoft.com/library/ms776317.aspx" mce_href="http://msdn2.microsoft.com/library/ms776317.aspx"&gt;GetNumberFormat&lt;/A&gt; can only take a string rather than a number due to the lack of a LOCALE_SPECIFY_NUMBER flag (as I mentioned in &lt;A class=" " href="http://blogs.msdn.com/michkap/archive/2005/05/29/422980.aspx" mce_href="http://blogs.msdn.com/michkap/archive/2005/05/29/422980.aspx"&gt;&lt;STRONG&gt;Pass the string please&lt;/STRONG&gt;&lt;/A&gt;, three years ago), the caller must format their number as a string via a function like _swprintf so that it can then format the number within the string as yet another a string -- and perhaps this is proof that I have changed my mind a bit since tha tblog; the NLS code really ought to help out more with the more common obvious cases when it can, such as this one.&lt;/P&gt;
&lt;P mce_keep="true"&gt;Second of all (and perhaps most importantly), the longstanding behavior of &lt;A class=" " href="http://msdn2.microsoft.com/library/ms776317.aspx" mce_href="http://msdn2.microsoft.com/library/ms776317.aspx"&gt;GetNumberFormat&lt;/A&gt;&amp;nbsp;that requires either a fully filled in NUMBERFMT in lpFormat or a NULL lpFormat means that the only way to specify an lpFormat-&amp;gt;NumDigits value is to also fill in the lpFormat-&amp;gt;LeadingZero, lpFormat-&amp;gt;Grouping, lpFormat-&amp;gt;lpDecimalSep, lpFormat-&amp;gt;ThousandSep, and lpFormat-&amp;gt;NegativeOrder values as well -- thus requiring up to five calls to GetLocaleInfo for information entirely derivable from the passed-in locale (assuming one value being overridden).&lt;/P&gt;
&lt;P mce_keep="true"&gt;There are any number of alternate possible ways it could have been done -- like establish the NULL case for the struct as being the default which means "take the locale's data", or specify values that mean the same thing, or even define flags to specify which values to pay attention to in the structure (there is room in the dwFlags for this both this function and GetCurrencyFormat!).&lt;/P&gt;
&lt;P mce_keep="true"&gt;Third of all,&amp;nbsp;where&amp;nbsp;&lt;A class=" " href="http://msdn2.microsoft.com/library/ms776317.aspx" mce_href="http://msdn2.microsoft.com/library/ms776317.aspx"&gt;GetNumberFormat&lt;/A&gt; always requires either a fully filled in NUMBERFMT in lpFormat or a NULL lpFormat, if you don't pass in that filled-in NUMBERFMT then the code behind the function always grabs all of the information even if it does not need it -- meaning for example that it will grab the user overridable lpFormat-&amp;gt;ThousandSep even if the number is not big enough to need it according to the number itself. The upshot of this is that the performance of the function is much better if you pass in the lpFormat yourself if you have the data handy -- because the function is not smart about how it does its work.&lt;/P&gt;
&lt;P mce_keep="true"&gt;Now one may argue against that type of optimization due to potential thread safety issues&amp;nbsp;caused by &lt;A class=" " href="http://msdn2.microsoft.com/library/ms776312.aspx" mce_href="http://msdn2.microsoft.com/library/ms776312.aspx"&gt;SetLocaleInfo&lt;/A&gt; calls happening while number formatting is happening, but given that this is already&amp;nbsp;really a bit&amp;nbsp;of a problem in the code terms of consistent number formatting in such situations&amp;nbsp;(and also how uncommon &lt;A class=" " href="http://msdn2.microsoft.com/library/ms776312.aspx" mce_href="http://msdn2.microsoft.com/library/ms776312.aspx"&gt;SetLocaleInfo&lt;/A&gt; calls or user-specific Regional Options changes that amount to &lt;A class=" " href="http://msdn2.microsoft.com/library/ms776312.aspx" mce_href="http://msdn2.microsoft.com/library/ms776312.aspx"&gt;SetLocaleInfo&lt;/A&gt; calls actually are), there are much better solutions for this problem that are possible. Much moreso&amp;nbsp;than the current solution (trying to front-load all of the data loading calls to minimize the number of possible &lt;A class=" " href="http://msdn2.microsoft.com/library/ms776312.aspx" mce_href="http://msdn2.microsoft.com/library/ms776312.aspx"&gt;SetLocaleInfo&lt;/A&gt; calls that could happen). And many of those better solutions would be more performant, too!&lt;/P&gt;
&lt;P mce_keep="true"&gt;On top of all that, this front-loading in the case of the NULL lpFormat happens when LOCAL:E_NOUSEROVERRIDE is specified, too -- meaning there is no thread safety issue all but the code is happy to fill a structure with six separate data items&amp;nbsp;without ever&amp;nbsp;returning the data it loaded to the caller (in case they were going to call the function repeatedly). If one has to pay the price, one would like a bit more for one's money, in my opinion....&lt;/P&gt;
&lt;P mce_keep="true"&gt;If those issues did not exist, then all of the work done by the third party GetDoubleFormat&amp;nbsp;could happen in a single very fast function call, rather than a whole bunch of code, such as the buggy code Igor pointed out in the version&amp;nbsp;of the third party application&amp;nbsp;he was looking at.&lt;/P&gt;
&lt;P mce_keep="true"&gt;Now none of this excuses the bugs in&amp;nbsp;the third party&amp;nbsp;application&amp;nbsp;-- that code screws up the usage of NLS functions with multiple&amp;nbsp;bugs including some that crash? They have no good reason to have those.&lt;/P&gt;
&lt;P mce_keep="true"&gt;But if the NLS function did a bit more of the work here, perhaps the kind of developers who were going to make those mistakes when left to their own devices would have one less opportunity to do so?&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;&lt;FONT color=#ff0000&gt;Now for the interactive bit of&amp;nbsp;this blog (and incidentally of this Blog):&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Any developers want to take a stab at implementing the &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;wchar_t *GetDoubleFormat(double Value, int DecimalPlaces)&lt;/STRONG&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;function without any of the numerous aforementioned&amp;nbsp;bugs? :-)&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;FONT color=#ff00ff&gt;&lt;EM&gt;This blog brought to you by&lt;/EM&gt;&lt;FONT size=5&gt; . &lt;/FONT&gt;&lt;EM&gt;(&lt;A class=" " href="http://www.fileformat.info/info/unicode/char/002e" mce_href="http://www.fileformat.info/info/unicode/char/002e"&gt;U+002e&lt;/A&gt;, aka FULL STOP)&lt;/EM&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8120567" width="1" height="1"&gt;&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=20344"&gt;</description><author>Sorting It All Out</author><pubDate>2008-03-10T00:00:00</pubDate><category>Object Oriented Concepts</category></item><item><title>Testing TempData in ASP.NET MVC</title><link>http://softlogger.com/18504/Object-Oriented-Concepts/testing-tempdata-in-asp-net-mvc.aspx</link><description>&lt;p&gt;
&lt;font style="BACKGROUND-COLOR: #f4f4f4"&gt;Eventually when testing your controllers you
will come across an action that sets TempData.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font style="BACKGROUND-COLOR: #f4f4f4"&gt;If you didn&amp;rsquo;t know, TempData is a session-backed
temporary storage dictionary that is available for one single request.&amp;nbsp; It&amp;rsquo;s
great to pass messages between controllers.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font style="BACKGROUND-COLOR: #f4f4f4"&gt;Our Controller classes that we derive from
have this as a member property.&amp;nbsp; However, when testing the controller, this always
came up as null.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font style="BACKGROUND-COLOR: #f4f4f4"&gt;Reflector is our friend here, so I fired it
up and loaded the Controller class.&amp;nbsp; Then I located the TempData member, and
looked at the setter.&amp;nbsp; It&amp;rsquo;s marked as internal, so somebody inside this
assembly is responsible for creating it.&amp;nbsp; &lt;/font&gt;&lt;font style="BACKGROUND-COLOR: #f4f4f4"&gt;By
using the Reflector Analyze feature, I was able to find exactly where the setter is
called.&amp;nbsp; It&amp;rsquo;s in the Execute() method.&amp;nbsp; (this is the general &amp;ldquo;pipeline&amp;rdquo;
method that all IController implementations must override)&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font style="BACKGROUND-COLOR: #f4f4f4"&gt;Think about that for a second.&amp;nbsp; At runtime,
the TempData dictionary is set because all requests flow through Execute().&amp;nbsp;
But in my test, I am specifically calling my action method.&amp;nbsp; There is no Execute()
in my test.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font style="BACKGROUND-COLOR: #f4f4f4"&gt;To top it off, I can&amp;rsquo;t set this guy
to a new TempDataDictionary because the setter is marked as internal.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font style="BACKGROUND-COLOR: #f4f4f4"&gt;&lt;a href="http://haacked.com/" target="_blank"&gt;Phil
Haack&lt;/a&gt; tells me they&amp;rsquo;re working on this issue so we&amp;rsquo;ll likely see an
improvement soon.&amp;nbsp; In the meantime you can get around the issue by using reflection
to set the value.&amp;nbsp; But first, can we create one?&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font style="BACKGROUND-COLOR: #f4f4f4"&gt;TempData is stored in session, so it needs
a reference to IHttpContext.&amp;nbsp; Thankfully, we can mock this, however we have to
make sure and mock the right parts.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font style="BACKGROUND-COLOR: #f4f4f4"&gt;First, create a mock for IHttpContext, create
the return values for mocked IHttpRequest &amp;amp; IHttpResponse.&amp;nbsp; Finally setup
return values for IHttpSession as well.&amp;nbsp; I&amp;rsquo;ve done all of this in a helper
method of my test (though it could be an extention method on the MockRepository ala
Phil, but whatever you like).&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;&lt;pre&gt;private IHttpContext GetHttpContext(string requestUrl)
{            
	IHttpRequest request = _mocks.DynamicMock&amp;lt;IHttpRequest&amp;gt;();
	SetupResult.For(request.Url).Return(new Uri(requestUrl));
&lt;/pre&gt;
&lt;pre&gt;	IHttpResponse response = _mocks.DynamicMock&amp;lt;IHttpResponse&amp;gt;();
	IHttpSessionState session = _mocks.DynamicMock&amp;lt;IHttpSessionState&amp;gt;();
        IHttpContext httpContext = _mocks.DynamicMock&amp;lt;IHttpContext&amp;gt;();

        _tempData = new TempDataDictionary(httpContext);
        SetupResult.For(session[null]).IgnoreArguments().Return(tempData);			

	SetupResult.For(httpContext.Session).Return(session);
	SetupResult.For(httpContext.Request).Return(request);
	SetupResult.For(httpContext.Response).Return(response);
        _mocks.Replay(session);
        _mocks.Replay(request);
        _mocks.Replay(response);
        _mocks.Replay(httpContext);&lt;/pre&gt;
&lt;pre&gt;        return httpContext;&lt;br /&gt;
} &lt;/pre&gt;
&lt;/code&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
This code is a little verbose, but this is something you write once and use in all
of your tests. You should notice that the &lt;code&gt;_tempData&lt;/code&gt; property is a local
field on my test class. I can then take this &lt;code&gt;_tempData&lt;/code&gt; variable and inject
it (via reflection) onto the controller under test. Here's how:
&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;typeof(FooController).GetProperty("TempData").SetValue(controller, _tempData, null);&lt;/pre&gt;
&lt;/code&gt; 
&lt;p&gt;
And now we can easily test that messages are set in TempData before redirecting or
rendering a view.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.flux88.com/aggbug.ashx?id=090db7e2-7462-4de2-bafa-ed005eccaed8" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/flux88?a=ku9sexD"&gt;&lt;img src="http://feeds.feedburner.com/~f/flux88?i=ku9sexD" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/flux88?a=F4Bpz6D"&gt;&lt;img src="http://feeds.feedburner.com/~f/flux88?i=F4Bpz6D" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/flux88?a=M0OGs8d"&gt;&lt;img src="http://feeds.feedburner.com/~f/flux88?i=M0OGs8d" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/flux88?a=TvjUFJD"&gt;&lt;img src="http://feeds.feedburner.com/~f/flux88?i=TvjUFJD" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/flux88?a=bnDHgmd"&gt;&lt;img src="http://feeds.feedburner.com/~f/flux88?i=bnDHgmd" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=18504"&gt;</description><author>Ben Scheirman                                                                                       </author><pubDate>2008-01-30T00:00:00</pubDate><category>Object Oriented Concepts</category></item><item><title>Using Inheritance in JavaScript Behaviors</title><link>http://softlogger.com/16806/Object-Oriented-Concepts/using-inheritance-in-javascript-behaviors.aspx</link><description>&lt;p&gt;While working on some samples using (different) menubar, I found it helpful to inherit a JavaScript Behavior from a more general JavaScript Behavior. This would give me the chance to implement the common general Javascript methods only once and leave specific functionality in the derived Behavior.&lt;/p&gt; &lt;p&gt;Here is the sample:&lt;/p&gt; &lt;p&gt;&lt;img height="24" src="http://www.mathertel.de/AJAX/Images/menubarsample.png"&gt;&lt;/p&gt;&lt;pre class="code"&gt;&lt;p&gt;&lt;span style="color: #008000"&gt;// this is a basic behavior definition for menubars&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; MenubarBehavior = {
&amp;nbsp; init: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt; () {
&lt;span style="color: #008000"&gt;    // activate the hover effect on all menu items&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;    var&lt;/span&gt; allitems = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.getElementsByTagName("&lt;span style="color: #8b0000"&gt;*&lt;/span&gt;");
&lt;span style="color: #0000ff"&gt;    for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; o &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; allitems)
&lt;span style="color: #0000ff"&gt;      if&lt;/span&gt; (allitems[o].className == "&lt;span style="color: #8b0000"&gt;VEMenu&lt;/span&gt;") {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; allitems[o].hover = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;},&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;  onkeypress: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(evt) {
    evt = evt || &lt;span style="color: #0000ff"&gt;window&lt;/span&gt;.event;
&lt;span style="color: #0000ff"&gt;    var&lt;/span&gt; kc = &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;.fromCharCode(evt.keyCode);
&lt;span style="color: #0000ff"&gt;    if&lt;/span&gt; ((&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._attachedBehaviour.onclick != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;/p&gt;&lt;p&gt;      &amp;amp;&amp;amp; (evt != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) &amp;amp;&amp;amp; ((kc == "&lt;span style="color: #8b0000"&gt; &lt;/span&gt;") || (kc == "&lt;span style="color: #8b0000"&gt;\r&lt;/span&gt;"))) {
&lt;span style="color: #0000ff"&gt;      this&lt;/span&gt;._attachedBehaviour.onclick.call(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;, evt);
    } &lt;span style="color: #008000"&gt;// if&lt;/span&gt;
  } &lt;span style="color: #008000"&gt;// onkeypressed&lt;/span&gt;
} &lt;span style="color: #008000"&gt;// MenubarBehavior&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;
&lt;p&gt;This is a basic implemenation that enables the hover effect for all VEMenu items found inside the menubar and to simulate a click event if the spacebar or return key is used while the focus is on a menuitem.&lt;/p&gt;&lt;pre class="code"&gt;&lt;p&gt;&lt;span style="color: #008000"&gt;// this is a basic behavior definition for menubars&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; EditMenubarBehavior = {
&amp;nbsp; inheritFrom: MenubarBehavior,&lt;/p&gt;&lt;p&gt; 
&amp;nbsp; init: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;() {
&amp;nbsp;&amp;nbsp;&amp;nbsp; MenubarBehavior.init.call(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;);
&amp;nbsp; },&lt;/p&gt;&lt;p&gt; 
  onclick: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(evt) {
    evt = evt || &lt;span style="color: #0000ff"&gt;window&lt;/span&gt;.event;
&lt;span style="color: #0000ff"&gt;    var&lt;/span&gt; src = evt.srcElement;
&lt;span style="color: #0000ff"&gt;    var&lt;/span&gt; cmd = src.&lt;span style="color: #0000ff"&gt;name&lt;/span&gt;;
&lt;span style="color: #0000ff"&gt;    if&lt;/span&gt; (cmd != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) {
      cmd = cmd.split(';');
      HtmlEditBehaviour.Command(cmd[0], cmd[1]);
    }
  } &lt;span style="color: #008000"&gt;// onclick&lt;/span&gt;
} &lt;span style="color: #008000"&gt;// EditMenubarBehavior&lt;/span&gt;&lt;/p&gt;&lt;/pre&gt;
&lt;p&gt;This is the implementation of the derived Behavior definition.&lt;/p&gt;
&lt;p&gt;If you ask why I do not use the JavaScript inheritance mechanism, then you have a good question - i tried.&lt;/p&gt;
&lt;p&gt;Using the new operator and the prototype mechanism does not work here because we attach methods to HTML elements and some other problems came up too.&lt;/p&gt;
&lt;p&gt;The article of Nicholas C. Zakas at: &lt;a title="http://www.sitepoint.com/article/javascript-objects" href="http://www.sitepoint.com/article/javascript-objects" target="_blank"&gt;http://www.sitepoint.com/article/javascript-objects&lt;/a&gt;&amp;nbsp;also describes the topic.&lt;/p&gt;
&lt;p&gt;You can find the state of the current implementation here:&lt;/p&gt;
&lt;p&gt;&lt;a title="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/InlineEditDemo.aspx" href="http://www.mathertel.de/AJAXEngine/S04_VisualEffects/InlineEditDemo.aspx" target="_blank"&gt;http://www.mathertel.de/AJAXEngine/S04_VisualEffects/InlineEditDemo.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;(see the page source by using the view link in the upper right corner)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The only code I had to add to the LoadBehaviour method (that does something very similar to the extends method of Zakas) are these 3 lines of code to recursively bind the Behaviors starting with the base class.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre class="code"&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (behaviour.inheritFrom != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) {
  &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.LoadBehaviour(obj, behaviour.inheritFrom);
  &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.List.pop();&lt;/p&gt;&lt;p&gt;}&lt;/p&gt;&lt;/pre&gt;
&lt;p&gt;See controls/jcl.js (&lt;a title="jcl.js source code" href="http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=controls/jcl.js" target="_blank"&gt;view source&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;(I'll publish a new version of the framework as a zip &lt;a href="http://www.mathertel.de/Downloads/Start_AJAX.aspx" target="_blank"&gt;here&lt;/a&gt; file when this sample is finished).&lt;/p&gt;&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=16806"&gt;</description><author>Aspects of AJAX</author><pubDate>2008-01-05T00:00:00</pubDate><category>Object Oriented Concepts</category></item><item><title>Data Layer Testing: Test Inheritance Patterns</title><link>http://softlogger.com/12975/Object-Oriented-Concepts/data-layer-testing-test-inheritance-patterns.aspx</link><description>&lt;p&gt;I'm preparing for my tutorial on Database and Data Layer unit testing that I will be giving at the Agile Practices Conference&amp;#160; next week. It's always nice to have a full 3 hours to get pretty deep into something. 75 minutes just isn't enough to grasp a concept deeply enough, just to graze it around the edges.&lt;/p&gt;  &lt;p&gt;When writing data layer tests, there are several patterns I've noticed, especially around the notion of inheritance within the test classes (Abstract test class pattern).&amp;#160; I've observed at least three different patterns emerging from inheritance that I've personally used, all relating to data layer testing, but could be used elsewhere:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Abstract Utility Class&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/rosherove/WindowsLiveWriter/DataLayerTestingTestInheritancePatterns_3770/image_2.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; margin: 0px 10px 0px 0px; border-left: 0px; border-bottom: 0px" height="243" alt="image" src="http://weblogs.asp.net/blogs/rosherove/WindowsLiveWriter/DataLayerTestingTestInheritancePatterns_3770/image_thumb.png" width="244" align="left" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt; This class will usually be a base class for tests written for data layer objects. it would contain &amp;quot;facilities&amp;quot; such as database helper classes, setup and teardown methods that would automatically rollback any test and anything else a derived base class that was testing a data layer object would need (helper methods for asserting complex stuff, for example).&lt;/p&gt;  &lt;p&gt;This is a classic &amp;quot;Abstract test class&amp;quot; pattern, and the next two are built on top of it.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Template Test Class&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/rosherove/WindowsLiveWriter/DataLayerTestingTestInheritancePatterns_3770/image_4.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; margin: 0px 10px 0px 0px; border-left: 0px; border-bottom: 0px" height="227" alt="image" src="http://weblogs.asp.net/blogs/rosherove/WindowsLiveWriter/DataLayerTestingTestInheritancePatterns_3770/image_thumb_1.png" width="244" align="left" border="0" /&gt;&lt;/a&gt;The template test class will contain &lt;em&gt;abstract&lt;/em&gt; methods as unit tests, which any derived class would have to override and perform. That means that if you are always testing the same things against a data layer object (insert returns different IDs, update works etc...) test authors on new data layer classes who derive from this class will never forget to implement at least these basic tests.&lt;/p&gt;  &lt;p&gt;they would also get the facilities for doing assertions and other things from the base class, as depicted in the previous pattern. makes sure you don't forget tests, saves some time on the infrastructure.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Abstract Driver Test Class&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/rosherove/WindowsLiveWriter/DataLayerTestingTestInheritancePatterns_3770/image_6.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; margin: 0px 10px 0px 0px; border-left: 0px; border-bottom: 0px" height="244" alt="image" src="http://weblogs.asp.net/blogs/rosherove/WindowsLiveWriter/DataLayerTestingTestInheritancePatterns_3770/image_thumb_2.png" width="228" align="left" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This class will have &lt;em&gt;non abstract&lt;/em&gt; test case methods inside it that will always run the same way. these test methods will call (using abstract methods) to the derived class' implementation of type specific actions (insert specific for a category, or update specific to person) .&lt;/p&gt;  &lt;p&gt;That leaves the derived class to only implement very basic things such as insert (and return the ID), update, or delete (by ID). the test methods in the base class will do the rest of the work. derived classes don't need to implement any tests unless they want to add type specific tests which don't belong on the base class.&lt;/p&gt;  &lt;p&gt;in the image to the left the green methods are tests that the base class runs, and the yellow ones are type specific helpers that the derived class has to implement.&lt;/p&gt;  &lt;p&gt;this makes writing tests for a new data layer object (as long as its interface is the same) very simple by inheriting a test class and implementing a few methods. all the test permutations in the base class will then run on the data layer object. saves lots of time and forgetting tests.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;What patterns have you come across?&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5369330" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/Iserializable?a=qncNkx"&gt;&lt;img src="http://feeds.feedburner.com/~a/Iserializable?i=qncNkx" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/Iserializable?a=J7dKU7B"&gt;&lt;img src="http://feeds.feedburner.com/~f/Iserializable?i=J7dKU7B" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Iserializable?a=4D1UPVB"&gt;&lt;img src="http://feeds.feedburner.com/~f/Iserializable?i=4D1UPVB" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/Iserializable?a=Rq8Jwgb"&gt;&lt;img src="http://feeds.feedburner.com/~f/Iserializable?i=Rq8Jwgb" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Iserializable/~4/192165310" height="1" width="1"/&gt;&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=12975"&gt;</description><author>ISerializable - Roy Osheroves Blog</author><pubDate>2007-11-29T00:00:00</pubDate><category>Object Oriented Concepts</category></item><item><title>Visual Basic 2008 - Introducing Extension Methods</title><link>http://softlogger.com/7620/Object-Oriented-Concepts/visual-basic-2008--introducing-extension-methods.aspx</link><description>&lt;TABLE class=MsoNormalTable style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; WIDTH: 100%; BORDER-BOTTOM: #c8cdde 1pt solid; mso-cellspacing: 1.5pt; mso-border-bottom-alt: solid #C8CDDE .5pt; mso-yfti-tbllook: 1184" cellSpacing=3 cellPadding=0 width="100%" border=1&gt;
&lt;TBODY&gt;
&lt;TR style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes"&gt;
&lt;TD style="BORDER-RIGHT: #f0f0f0; PADDING-RIGHT: 12pt; BORDER-TOP: #f0f0f0; PADDING-LEFT: 0.75pt; PADDING-BOTTOM: 0.75pt; BORDER-LEFT: #f0f0f0; PADDING-TOP: 0.75pt; BORDER-BOTTOM: #c8cdde; BACKGROUND-COLOR: transparent"&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 11.5pt; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;STRONG&gt;Note: &lt;/STRONG&gt;&lt;FONT size=1&gt;This article is based on&amp;nbsp;Orcas Beta 2 (Visual Studio 2008).&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;B&gt;&lt;SPAN style="FONT-SIZE: 11.5pt; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;/SPAN&gt;&lt;/B&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;B&gt;&lt;SPAN style="FONT-SIZE: 11.5pt; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;Extension Methods&lt;/SPAN&gt;&lt;/B&gt;&lt;SPAN style="FONT-SIZE: 9.5pt; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;Visual Basic 2008 extension methods enable you to "add" functionality to existing types without creating a new derived type.&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H1 style="MARGIN: 0.15in 0in 4.8pt"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Verdana','sans-serif'; mso-bidi-font-size: 11.0pt"&gt;Types That Can Be Extended&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/H1&gt;
&lt;P class=MsoNormal style="MARGIN: 1.2pt 0in 1.2pt 22.5pt; TEXT-INDENT: -5.7pt; LINE-HEIGHT: normal; mso-list: l0 level1 lfo1; tab-stops: 22.5pt list 65.1pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol; mso-bidi-font-size: 8.5pt"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&amp;#183;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Classes (reference types) &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 1.2pt 0in 1.2pt 22.5pt; TEXT-INDENT: -5.7pt; LINE-HEIGHT: normal; mso-list: l0 level1 lfo1; tab-stops: 22.5pt list 65.1pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol; mso-bidi-font-size: 8.5pt"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&amp;#183;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Structures (value types) &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 1.2pt 0in 1.2pt 22.5pt; TEXT-INDENT: -5.7pt; LINE-HEIGHT: normal; mso-list: l0 level1 lfo1; tab-stops: 22.5pt list 65.1pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol; mso-bidi-font-size: 8.5pt"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&amp;#183;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Interfaces &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 1.2pt 0in 1.2pt 22.5pt; TEXT-INDENT: -5.7pt; LINE-HEIGHT: normal; mso-list: l0 level1 lfo1; tab-stops: 22.5pt list 65.1pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol; mso-bidi-font-size: 8.5pt"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&amp;#183;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Delegates &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 1.2pt 0in 1.2pt 22.5pt; TEXT-INDENT: -5.7pt; LINE-HEIGHT: normal; mso-list: l0 level1 lfo1; tab-stops: 22.5pt list 65.1pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol; mso-bidi-font-size: 8.5pt"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&amp;#183;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'"&gt;ByRef and ByVal arguments &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 1.2pt 0in 1.2pt 22.5pt; TEXT-INDENT: -5.7pt; LINE-HEIGHT: normal; mso-list: l0 level1 lfo1; tab-stops: 22.5pt list 65.1pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol; mso-bidi-font-size: 8.5pt"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&amp;#183;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Generic method parameters &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 1.2pt 0in 1.2pt 22.5pt; TEXT-INDENT: -5.7pt; LINE-HEIGHT: normal; mso-list: l0 level1 lfo1; tab-stops: 22.5pt list 65.1pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol; mso-bidi-font-size: 8.5pt"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&amp;#183;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Arrays &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Extension methods make it possible to create a method in a Visual Basic module that can be called&amp;nbsp;as if it were an instance method of another type.&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;An extension method can be a &lt;SPAN class=keyword&gt;&lt;STRONG&gt;Sub&lt;/STRONG&gt;&lt;/SPAN&gt; procedure or a &lt;SPAN class=keyword&gt;&lt;STRONG&gt;Function&lt;/STRONG&gt;&lt;/SPAN&gt; procedure. You cannot define an extension property, field, or event. All extension methods must be marked with the extension attribute &lt;/SPAN&gt;&lt;SPAN class=code&gt;&lt;SPAN style="FONT-SIZE: 9pt; LINE-HEIGHT: 115%"&gt;&lt;FONT face="Courier New" color=#000066&gt;&lt;EXTENSION()&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;from the &lt;SPAN class=linkterm&gt;System.Runtime.CompilerServices&lt;/SPAN&gt; namespace.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;The first parameter in an extension method definition specifies which data type the method extends. When the method is run, the first parameter is bound to the instance of the data type that invokes the method.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;In the following example an extension method is defined for the .NET String type.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3 style="MARGIN: 10pt 0in 2.4pt"&gt;&lt;SPAN style="FONT-SIZE: 9pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'; mso-bidi-font-size: 10.0pt"&gt;Example &amp;#8211; Add &amp;#8216;Display&amp;#8217; extension method to .NET String type&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;The following code defines a &lt;/SPAN&gt;&lt;SPAN class=code&gt;&lt;SPAN style="FONT-SIZE: 9pt; LINE-HEIGHT: 115%"&gt;&lt;FONT face="Courier New" color=#000066&gt;Display&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt; extension method for the .NET &lt;SPAN class=linkterm&gt;String&lt;/SPAN&gt; data type. The method uses &lt;/SPAN&gt;&lt;SPAN class=code&gt;&lt;SPAN style="FONT-SIZE: 9pt; LINE-HEIGHT: 115%"&gt;&lt;FONT face="Courier New" color=#000066&gt;MessageBox.Display&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt; to display a string. The type of the &lt;/SPAN&gt;&lt;SPAN class=code&gt;&lt;SPAN style="FONT-SIZE: 9pt; LINE-HEIGHT: 115%"&gt;&lt;FONT face="Courier New" color=#000066&gt;aString&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt; parameter of the &lt;/SPAN&gt;&lt;SPAN class=code&gt;&lt;SPAN style="FONT-SIZE: 9pt; LINE-HEIGHT: 115%"&gt;&lt;FONT face="Courier New" color=#000066&gt;Display&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt; method, establishes that the method extends the &lt;SPAN class=linkterm&gt;String&lt;/SPAN&gt; class.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;' You must define type extensions in a Visual Basic module.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;Module&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; ExampleTypeExtensions&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;'All extension methods must be marked with the extension attribute &lt;EXTENSION()&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;'&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;from the System.Runtime.CompilerServices namespace.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SYSTEM.RUNTIME.COMPILERSERVICES.EXTENSION()&gt;_&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Display(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; aString &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;String&lt;/SPAN&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;MessageBox.Show(aString)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt 0.5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;End&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; &lt;SPAN style="COLOR: blue"&gt;Module&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;The following code, in a button click handler in a Windows form, calls the String &amp;#8216;Display&amp;#8217; extension method defined above.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;Public&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; &lt;SPAN style="COLOR: blue"&gt;Class&lt;/SPAN&gt; Form1&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; DisplayStringButton_Click _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; sender &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; System.Object, &lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; e &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; System.EventArgs) _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Handles&lt;/SPAN&gt; DisplayStringButton.Click&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Dim&lt;/SPAN&gt; name &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;String&lt;/SPAN&gt; = &lt;SPAN style="COLOR: #a31515"&gt;"John Doe"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;name.Display()&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt 0.5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;End&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; &lt;SPAN style="COLOR: blue"&gt;Class&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt 0.5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt"&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Result&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt 0.5in; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-no-proof: yes"&gt;&lt;?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /&gt;&lt;v:shapetype id=_x0000_t75 stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"&gt;&lt;v:stroke joinstyle="miter"&gt;&lt;/v:stroke&gt;&lt;v:formulas&gt;&lt;v:f eqn="if lineDrawn pixelLineWidth 0"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum @0 1 0"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum 0 0 @1"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @2 1 2"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @3 21600 pixelWidth"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @3 21600 pixelHeight"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum @0 0 1"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @6 1 2"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @7 21600 pixelWidth"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum @8 21600 0"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @7 21600 pixelHeight"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum @10 21600 0"&gt;&lt;/v:f&gt;&lt;/v:formulas&gt;&lt;v:path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"&gt;&lt;/v:path&gt;&lt;o:lock aspectratio="t" v:ext="edit"&gt;&lt;/o:lock&gt;&lt;/v:shapetype&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;o:p&gt;The name 'John Doe' is displayed in a message box.&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt"&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Notes&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;You can use extension methods to extend a type&amp;#8217;s methods, but not to override them. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;All that is required to be able to run extension methods is that they be in scope. If an extension method is in scope, it is visible in IntelliSense and can be called as if it were an ordinary instance method.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Notice that when the &amp;#8216;Display&amp;#8217; extension method is invoked in example, no argument is sent in for the first parameter. Parameter &lt;/SPAN&gt;&lt;SPAN class=code&gt;&lt;SPAN style="FONT-SIZE: 9pt; LINE-HEIGHT: 115%"&gt;&lt;FONT face="Courier New" color=#000066&gt;aString&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt; in the extension method definition is automatically bound to the instance of &lt;SPAN class=keyword&gt;&lt;STRONG&gt;String&lt;/STRONG&gt;&lt;/SPAN&gt; that calls them. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;Because the first parameter specifies the data type that the extension method extends, it is required and cannot be optional. For that reason, &lt;SPAN class=keyword&gt;&lt;STRONG&gt;Optional&lt;/STRONG&gt;&lt;/SPAN&gt; parameters and &lt;SPAN class=keyword&gt;&lt;STRONG&gt;ParamArray&lt;/STRONG&gt;&lt;/SPAN&gt; parameters are excluded.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;When an extension method has the same name as an existing method but a different signature, both methods are allowed as long as the signatures do not conflict.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;When an extension method has the same name and signature as an existing method in the type being extended, resolve ambiguity by using the fully qualified name to specify the extension method you are calling. In the example the Display extension method is defined in a module named &lt;/SPAN&gt;&lt;SPAN class=code&gt;&lt;SPAN style="FONT-SIZE: 9pt; LINE-HEIGHT: 115%"&gt;&lt;FONT face="Courier New" color=#000066&gt;ExampleTypeExtensions&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;, the fully qualified name is &lt;/SPAN&gt;&lt;SPAN class=code&gt;&lt;SPAN style="FONT-SIZE: 9pt; LINE-HEIGHT: 115%"&gt;&lt;FONT face="Courier New" color=#000066&gt;ExampleTypeExtensions.Display&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;In general, it is recommended that you implement extension methods sparingly. When possible, client code that extends an existing type should do so by creating a new type derived from the existing type.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;When using an extension method to extend a type whose source code you cannot change, you run the risk that a change in the implementation of the type will cause your extension method to break.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;Mike McIntyre&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 6pt 0in 3pt; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&lt;A href="http://www.getdotnetcode.com"&gt;http://www.getdotnetcode.com&lt;/A&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;img src ="http://blogs.vbcity.com/mcintyre/aggbug/8721.aspx" width = "1" height = "1" /&gt;&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=7620"&gt;</description><author>mike mcintyres</author><pubDate>2007-09-21T00:00:00</pubDate><category>Object Oriented Concepts</category></item><item><title>Entity Framework - Post 1 of &amp;amp;quot;Many&amp;amp;quot;, providing some links</title><link>http://softlogger.com/7311/Object-Oriented-Concepts/entity-framework--post-1-of-many-providing-some-links.aspx</link><description>&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note: Some of the posts referenced in this post (!) are likely to be more out of date than others but I still feel that they are very much worth reading.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Whilst &lt;a href="http://blogs.msdn.com/adonet/archive/2007/08/03/entity-framework-beta-2.aspx"&gt;waiting for new Entity Framework bits&lt;/a&gt; to experiment with :-) I thought I'd start to write something about the Entity Framework and expand it over the coming weeks or months. This is mainly a "link" post to pull a few things together.&lt;/p&gt; &lt;p&gt;The Entity Framework is a new technology from the ADO.NET team. &lt;/p&gt; &lt;p&gt;The last time we had goodies from ADO.NET, it was in ADO.NET V2.0 where we (just like in V1.0) had the abstracted &lt;strong&gt;DataSet, DataTable&lt;/strong&gt; and the provider-specific &lt;strong&gt;Connection, Reader, Adapter, Command&lt;/strong&gt; classes that interact with a specific store. &lt;/p&gt; &lt;p&gt;You get a level of abstraction from ADO.NET 2.0 because you can program through generic interfaces rather than get involved with the particulars of (say) a &lt;strong&gt;SqlCommand&lt;/strong&gt; or an &lt;strong&gt;OracleCommand&lt;/strong&gt; but, ultimately, you still end up writing code that is store specific because you have to use T-SQL or PL/SQL with those commands in the end and differences in the underlying stores (such as what happens with stored procedures) ultimately bubble up through the abstraction.&lt;/p&gt; &lt;p&gt;There are also some factory bits in ADO.NET V2.0 to make it easier to create one or another provider's &lt;strong&gt;Commands &lt;/strong&gt;(etc) by hiding the creation behind a factory wall.&lt;/p&gt; &lt;p&gt;So that's where we've been for quite a few years now but when ADO.NET 3.0 comes along it brings with it a whole new level of abstraction with the Entity Framework which has the potential to have a huge impact on the way in which we access data.&lt;/p&gt; &lt;p&gt;The&amp;nbsp;big new idea of the Entity Framework&amp;nbsp;is to stop querying the data store directly altogether and to start querying a conceptual model (an ER model) instead with a mapping technology that can translate your queries to the specifics of a store.&lt;/p&gt; &lt;p&gt;&lt;a href="http://mtaulty.com/blog/images/TheMortalsGuidetotheEntityFrameworkPost1_14DD9/image.png"&gt;&lt;img height="58" alt="image" src="http://mtaulty.com/blog/images/TheMortalsGuidetotheEntityFrameworkPost1_14DD9/image_thumb.png" width="640" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;The Entity Framework calls this conceptual model the "Entity Data Model" or EDM.&lt;/p&gt; &lt;p&gt;This has a bunch of advantages such as;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;The logical model of the relational store often isn't what an application developer wants to program against and writing explicit code to map it isn't productive. &lt;li&gt;The logical model of the relational store often isn't what a report writer wants to write a report against (and we've already seen a similar mapping approach in today's Reporting Services).  &lt;li&gt;It's not always desirable to tie the application to the specific SQL dialect of&amp;nbsp;one store (but it's very difficult to avoid it with ADO.NET 2.0).  &lt;li&gt;It would be nice to make modifications to the store without altering the app but, instead, just altering the mapping.  &lt;li&gt;It would be nice to potentially move to a different store without modifying the app but, instead, just altering the mapping.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;You can get a lot more background information on the Entity Framework by;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;a href="http://blogs.msdn.com/adonet/archive/2006/07/11/662454.aspx"&gt;Watching the screencasts linked to from here&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/Aa697427(VS.80).aspx"&gt;Checking out the whitepaper here&lt;/a&gt;.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;And you can learn more about the Entity Data Model by;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/aa697428(VS.80).aspx"&gt;Reading the whitepaper here&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="http://blogs.msdn.com/adonet/archive/2007/01/30/entity-data-model-part-1.aspx"&gt;Reading this post&lt;/a&gt;&amp;nbsp;and then &lt;a href="http://blogs.msdn.com/adonet/archive/2007/02/12/entity-data-model-101-part-2.aspx"&gt;following it with this post&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Possibly adding in some of &lt;a href="http://blogs.msdn.com/adonet/archive/2006/09/13/752865.aspx"&gt;this post&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;In order to make all this work the Entity Framework has to be capable of offering query capabilities against the&amp;nbsp;EDM whilst translating those to the logical model of the store.&lt;/p&gt; &lt;p&gt;It does this by providing a new ADO.NET provider, the &lt;strong&gt;EntityClient&lt;/strong&gt; provider which slots into the existing ADO.NET extensibility model by providing a &lt;strong&gt;Command, Reader, Adapter, Connection&lt;/strong&gt;. &lt;/p&gt; &lt;p&gt;In order to learn a little more about &lt;strong&gt;EntityClient&lt;/strong&gt; check out;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;a href="http://blogs.msdn.com/adonet/archive/2007/02/14/entity-client.aspx"&gt;This post on EntityClient&lt;/a&gt;&lt;/li&gt; &lt;li&gt;And &lt;a href="http://blogs.msdn.com/adonet/archive/2007/03/16/ado-net-orcas-sample-provider.aspx"&gt;this post&lt;/a&gt; which explains what this means for provider writers to plug-in to Entity Framework (i.e. it's not &lt;em&gt;free :-)&lt;/em&gt;)&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Queries written against the &lt;strong&gt;EntityClient&lt;/strong&gt; are written in Entity SQL (eSQL) which looks like SQL languages that we already know and love but also has some pretty snazzy capabilities. &lt;/p&gt; &lt;p&gt;To learn more about Entity SQL;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Check out &lt;a href="http://blogs.msdn.com/adonet/archive/2007/05/30/entitysql.aspx"&gt;this post&lt;/a&gt;&amp;nbsp;(warning - this post requires caffeine as it's &lt;em&gt;really&lt;/em&gt; &lt;em&gt;good&lt;/em&gt; but quite long and fairly complex in places).&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;In order to translate those queries for the specific store, the &lt;strong&gt;EntityClient&lt;/strong&gt; provider has to perform a translation which it does by consulting 3 metadata models (typically, but not necessarily (AFAIK), provided as XML documents);&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Your EDM - this is&amp;nbsp;described in "Conceptual Schema Definition Language" (CSDL).  &lt;li&gt;Your store - this is described in "Store Schema Definition Language" (SSDL).  &lt;li&gt;The translation between the two - this is described in "Mapping Schema Language" (MSL).&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Of these, the SSDL is perhaps the most likely one that you can just have generated for you by pointing a tool (and there is one - &lt;strong&gt;edmgen.exe&lt;/strong&gt;) at an existing store and saying "get me the SSDL from that store".&lt;/p&gt; &lt;p&gt;As it happens, you can also get CSDL and MSL generated but that's only really going to work for the scenario where you have a 1:1 mapping between your EDM and your store.&lt;/p&gt; &lt;p&gt;To learn more about Mapping;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;a href="http://blogs.msdn.com/adonet/archive/2007/02/26/mapping-101-part-1.aspx"&gt;Start here&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href="http://blogs.msdn.com/adonet/archive/2007/05/10/mapping-101-part-2-association-mapping.aspx"&gt;Carry on here&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href="http://blogs.msdn.com/adonet/archive/2006/09/13/752865.aspx"&gt;Try a bit of this too&lt;/a&gt;.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;So, with those necessary bits and pieces in place you can now do the "ADO.NET thing" and query this EDM model through the &lt;strong&gt;EntityClient&lt;/strong&gt; provider in order to execute eSQL against that conceptual data model. So, you can write code like;&lt;/p&gt; &lt;blockquote&gt;&lt;pre&gt;EntityCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT p.ProductName, p.UnitPrice FROM NorthwindEntities.Product AS p";&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;And if you go ahead and execute that command and get yourself a reader and that reader will come back with 2 "columns" in it and it's the same old procedure that we're used to to enumerate and get those values out (i.e. while (reader.Read()) { reader["ProductName"], reader["UnitPrice"] }&lt;/p&gt;
&lt;p&gt;To learn more about querying;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Read &lt;a href="http://blogs.msdn.com/adonet/archive/2006/08/21/710862.aspx"&gt;this post&lt;/a&gt;.&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Something important to point out here - as far as I'm aware, you can only &lt;em&gt;query&lt;/em&gt; the EDM model via eSQL. You can't update it that way - from looking at the current eSQL command reference there is no INSERT, UPDATE, DELETE right now and so you have to rely on other services of the &lt;strong&gt;EntityClient&lt;/strong&gt; provider to do the CUD parts of your CRUD operations.&lt;/p&gt;
&lt;p&gt;At that point you might be thinking - "Huh? What other services?" because the provider is already doing quite a bit of work to offer up this new SQL-like language and translate it into the underlying logical schema but it does a lot more than that. It also offers&amp;nbsp;something that goes by the&amp;nbsp;name of &amp;nbsp;"Object Services" which essentially takes the &lt;strong&gt;EntityClient&lt;/strong&gt; and its EDM and offers Object Relational Mapping on top of that.&lt;/p&gt;
&lt;p&gt;As far as I know, the mapping between the .NET Type layer and the EDM layer is 1:1 right now but I think that's just a default rather than a limitation. So, you can get direct access to the EDM by pulling collections of .NET types (e.g. the &lt;strong&gt;Customer&lt;/strong&gt; type for the &lt;strong&gt;Customer&amp;nbsp;&lt;/strong&gt;entity&amp;nbsp;defined in the EDM) out of the store and programming against them. The "Object Services" layer includes things that we've seen before in ORM layers including things like identity management, change tracking, transaction integration/management, automatic generation of insert/update/delete operations, concurrency management, integration of stored procedures and/or functions,&amp;nbsp;easy navigation of relationships&amp;nbsp;and so on&lt;/p&gt;
&lt;p&gt;To follow up (a little - it's not a very long post) on Object Services check out;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/adonet/archive/2007/03/01/object-services-write-less-code.aspx"&gt;This post&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;and there's some specifics around;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/adonet/archive/2007/03/15/inheritance-in-the-entity-framework.aspx"&gt;Inheritance&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/adonet/archive/2007/03/08/using-stored-procedures-for-change-processing-in-the-ado-net-entity-framework.aspx"&gt;Stored Procedures&lt;/a&gt;.&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Also, there's quite a lot in &lt;a href="http://blogs.msdn.com/adonet/archive/2007/05/30/entitysql.aspx"&gt;that post I referenced on eSQL&lt;/a&gt; about how results are projected that plays into these object capabilities as well.&lt;/p&gt;
&lt;p&gt;Now, it really wouldn't be very good if all of these capabilities didn't tie in to the "new kid on the block" - i.e. LINQ coming with Visual Studio 2008 so, depending on your needs, you can choose to write eSQL yourself or you can go ahead and use LINQ to Entities and define the queries using your language syntax (against the .NET types generated from your EDM) and get all the benefits of compile time checking, IntelliSense and so on that LINQ gives you.&lt;/p&gt;
&lt;p&gt;That's pretty much all the references I wanted to share except that there's also an &lt;a href="http://msdn.microsoft.com/msdnmag/issues/07/07/DataPoints/default.aspx"&gt;MSDN Magazine article&lt;/a&gt;&amp;nbsp;to take a look at as well - provides a very good overview.&lt;/p&gt;
&lt;p&gt;If you've managed to read all of this stuff then (like me) you're probably chomping at the bit for new Entity Framework bits to go with Visual Studio 2008. Maybe it's &lt;a href="http://blogs.msdn.com/adonet/archive/2007/08/03/entity-framework-beta-2.aspx"&gt;time to check back&lt;/a&gt;&amp;nbsp;and see if they came out yet! :-)&lt;/p&gt;&lt;img src="http://mtaulty.com/CommunityServer/aggbug.aspx?PostID=9573" width="1" height="1"&gt;&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=7311"&gt;</description><author>Mike Taultys Blog</author><pubDate>2007-08-09T00:00:00</pubDate><category>Object Oriented Concepts</category></item><item><title>Operator Overloading Considered Insanely Useful</title><link>http://softlogger.com/12231/Object-Oriented-Concepts/operator-overloading-considered-insanely-useful.aspx</link><description>&lt;p&gt;&lt;a href="http://technorati.com/tag/Programming" rel="tag"&gt;Programming&lt;/a&gt;, &lt;a href="http://technorati.com/tag/SelfDocumenting" rel="tag"&gt; SelfDocumenting&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Sugar" rel="tag"&gt; Sugar&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Syntax" rel="tag"&gt; Syntax&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am amazed that for all the talk about future Java features, there is hardly any mention of operator overloading. Certainly syntactic sugar is high on the priority list, with the Java world starting to realise the benefits of powerful literals and closures. (Good thing too. &lt;a href="http://steve-yegge.blogspot.com/2006/09/bloggers-block-4-ruby-and-java-and.html"&gt;Steve Yegge:&lt;/a&gt; "Java's biggest failing, I've decided, is its lack of syntax for literal data objects. It's an umbrella failing that accounts for most of the issues I have with the language."). Yet operator overloading is another feature that no real-world language should be without, and hardly anyone gives a second thought to the fact that time has moved on since the concept was rejected in 1995.&lt;/p&gt;

&lt;p&gt;In Java:&lt;/p&gt;

&lt;p&gt;earnings2007.greaterThan(earnings2008)&lt;/p&gt;

&lt;p&gt;In Ruby/Python/C++/C#/anyOtherDynamicOrNonDynamicLanguage:&lt;/p&gt;

&lt;p&gt;earnings2007 &gt; earnings2008&lt;/p&gt;

&lt;p&gt;Of course, many a Java destractor has noted the irony that is String."+" overloading, which is to say that Java's creators broke the rule and did something you can't do, by making "a"+"b" a legal operation, even though String in theory is just a run-of-the-mill Java class. This is a subtle way of saying maybe there are cases where operator overloading makes sense; at least, the people who prohibited it thought so. I think it's called "do as I say...".&lt;/p&gt;

&lt;p&gt;The arguments against operator overloading are pretty much the same as those against dynamic classing and make a trade-off in favour of robustness over productivity which is rarely warranted. The reality is that production errors are hardly ever caused by typing confusion, as long as you make the operator definitions meaningful. I can trust you to do that because you're a professional, right? Even if your testing regime consists of nothing more than dipping your web server into your bowl of Corn Flakes every weekend, I challenge you to come up with a production error caused by confusing String.+() with Integer.+(). If you can grok earnings2007.greaterThan(earnings2008), I'm sure you'll do just fine with earnings2007 &gt; earning2008. The only problem with operator overloading comes when people do stoopid things with operators, and you can just as equally do stoopid things with method names (or &lt;a href="http://en.wikipedia.org/wiki/FALSE"&gt;booleans&lt;/a&gt; if you want to get really sad &lt;img src='http://softwareas.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /&gt; ), so why victimise the operator?&lt;/p&gt;

&lt;p&gt;People will say "can't have operator overloading - it leads to weird code that doesn't make sense", which would be like banning electric guitars because someone might use it to make weird music.&lt;/p&gt;

&lt;p&gt;I would take overloading further than what we do today. e.g. how about multiple operands:&lt;/p&gt;

&lt;p&gt;assert(x &lt; y &lt; z)&lt;/p&gt;

&lt;p&gt;You could do that with today's terminology by having &lt; return some kind of state object instead of just a boolean. So what I'm talking here is as much about patterns as new language features.&lt;/p&gt;

&lt;p&gt;How about more &lt;a href="http://www.zipcon.net/~swhite/docs/math/math.html"&gt;visual representations&lt;/a&gt;:&lt;/p&gt;

&lt;div class="math"&gt;
    &lt;span class="int"&gt;∫&lt;sub&gt;Ω&lt;/sub&gt;&lt;sup&gt; &lt;/sup&gt;&lt;/span&gt;
        &lt;i&gt;v&lt;/i&gt; Δ &lt;i&gt;u&lt;/i&gt; &lt;i&gt;dx&lt;/i&gt;

     = 
    &lt;span class="int"&gt;∫&lt;sub&gt;Ω&lt;/sub&gt;&lt;sup&gt; &lt;/sup&gt;&lt;/span&gt;
    &lt;span class="sum"&gt;∑&lt;sup&gt; &lt;/sup&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;&lt;/span&gt;
        &lt;i&gt;v&lt;/i&gt;&lt;sub&gt;&lt;i&gt;x&lt;/i&gt;&lt;/sub&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt; 
        &lt;i&gt;u&lt;/i&gt;&lt;sub&gt;&lt;i&gt;x&lt;/i&gt;&lt;/sub&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt; 
        &lt;i&gt;dx&lt;/i&gt;

     + 
    &lt;span class="int"&gt;∫&lt;sub&gt;∂Ω&lt;/sub&gt;&lt;sup&gt; &lt;/sup&gt;&lt;/span&gt;
        &lt;i&gt;v&lt;/i&gt; 
        &lt;table class="fraction" cellpadding="0" cellspacing="0"&gt;
        &lt;tr&gt;&lt;td class="numerator"&gt;
            &lt;i&gt;d&lt;/i&gt;&lt;i&gt;u&lt;/i&gt;
        &lt;/td&gt;&lt;/tr&gt;

        &lt;tr&gt;&lt;td class="divider"&gt;----&lt;/td&gt;&lt;/tr&gt;
        &lt;tr&gt;&lt;td class="denominator"&gt;
            &lt;i&gt;d&lt;/i&gt;&lt;i&gt;n&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;
        &lt;/table&gt;
         &lt;i&gt;d&lt;/i&gt;&lt;i&gt;S&lt;/i&gt;
&lt;/div&gt;

&lt;p&gt;Yes, that's right, a formula that looks like a formula. Surely this is the natural extrapolation from current trends - (a) domain-specific languages, where the code looks like the requirement; (b) smart IDEs. I discussed this &lt;a href="http://softwareas.com/source-code-string-of-ascii-or-tree-of-goodness"&gt;a while back&lt;/a&gt; with reference to the (now-defunct?) Jackpot project. Operator overloading is one piece of that puzzle.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://picupper.com/2007/08/03/cookiej.jpg" /&gt;&lt;/p&gt;
&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=12231"&gt;</description><author>Software As Shes Developed</author><pubDate>2007-08-03T00:00:00</pubDate><category>Object Oriented Concepts</category></item><item><title>BCL Refresher: Converting the Non-Generic Collections [Inbar Gazit]</title><link>http://softlogger.com/7223/Object-Oriented-Concepts/bcl-refresher-converting-the-non-generic-collections-inbar-gazit.aspx</link><description>&lt;p&gt;As you know generics were only introduced to the .NET Framework in version 2.0. Originally we had a lot of collections in the System.Collections namespace that can store objects. In version 2.0 we added the System.Collections.Generic namespace to support generic collections that can store any specific type.&lt;/p&gt;  &lt;p&gt;If you have legacy code or even if you kept using the old non-generic collections for other reasons you may want to consider converting your code to use the generic collections instead. Here are a few reasons why:&lt;/p&gt;  &lt;ol&gt; 	&lt;li&gt;&lt;b&gt;Readability and simplicity of your code&lt;/b&gt;. Let’s take the case of getting the first  string in a list of strings. With generics you would declare List&amp;lt;T&amp;gt;  myList = new List&amp;lt;T&amp;gt;(); and then say string firstString = myList[0] just like working with arrays. This syntax is much more simple and readable than what you used to have to write which was ArrayList myList = new ArrayList(); and then string firstString = myList[0] as string;&lt;/li&gt; 	&lt;li&gt;&lt;b&gt;Performance&lt;/b&gt;. Every time you add a value type to a non-generic collection you have to box it to make it an object and every time you retrieve a value type from a non-generic collection you have to unbox it back from object. Even with reference type you still need to cast back to the correct type when retrieving items.&lt;/li&gt; 	&lt;li&gt;&lt;b&gt;Working against new smaller Framework SKUs&lt;/b&gt;. In Silverlight we decided to remove all the concrete non-generic collections completely from the codebase. This is mostly because the Silverlight core managed libraries is set to be the smallest useful set of classes. It’s also possible that other future small frameworks will not have the non-generic collections in store. If you ever plan to write code for those frameworks — you should convert it to use the generic collections.&lt;/li&gt; 	&lt;li&gt;&lt;b&gt;Better type-safe libraries&lt;/b&gt;. If you are developing libraries to be consumed by 3&lt;sup&gt;rd&lt;/sup&gt; parties you should most definitely use generic collections when possible. This would allow consumer of your libraries to quickly figure out what’s expected to be stored in the collections instead of having to guess or figure out from documentation.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;OK, so now I convinced you that you should go back and revise your existing code (not to mention any new code you’re writing) to use generic collection but how exactly should you go about it?&lt;/p&gt;  &lt;p&gt;Luckily, most of the non-generic collections (with the exception of BitArray) have very good generic counterparts. The following table illustrates what type to replace for what:&lt;/p&gt;  &lt;table class="post"&gt;  &lt;tbody&gt;&lt;tr&gt;   &lt;td&gt;&lt;b&gt;Non-generic&lt;/b&gt;&lt;/td&gt;   &lt;td&gt;&lt;b&gt;Generic replacement&lt;/b&gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td&gt;ArrayList&lt;/td&gt;   &lt;td&gt;List&amp;lt;T&amp;gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td&gt;BitArray&lt;/td&gt;   &lt;td&gt;List&amp;lt;Boolean&amp;gt; [note that this isn’t stored   as compactly as BitArray but represents the same information]&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td&gt;CaseInsensitiveComparer&lt;/td&gt;   &lt;td&gt;Comparer&amp;lt;T&amp;gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td&gt;CaseInsensitiveHashCodeProvider&lt;/td&gt;   &lt;td&gt;Comparer&amp;lt;T&amp;gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td&gt;CollectionBase&lt;/td&gt;   &lt;td&gt;Collection&amp;lt;T&amp;gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td&gt;Comparer&lt;/td&gt;   &lt;td&gt;Comparer&amp;lt;T&amp;gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td&gt;CompatibleComparer&lt;/td&gt;   &lt;td&gt;Comparer&amp;lt;T&amp;gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td&gt;DictionaryBase&lt;/td&gt;   &lt;td&gt;KeyedCollection&amp;lt;K,V&amp;gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td&gt;DictionaryEntry&lt;/td&gt;   &lt;td&gt;KeyValuePair&amp;lt;K,V&amp;gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td&gt;Hashtable&lt;/td&gt;   &lt;td&gt;Dictionary&amp;lt;K,V&amp;gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td&gt;KeyValuePairs&lt;/td&gt;   &lt;td&gt;KeyValuePair&amp;lt;K,V&amp;gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td&gt;Queue&lt;/td&gt;   &lt;td&gt;Queue&amp;lt;T&amp;gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td&gt;ReadOnlyCollectionBase&lt;/td&gt;   &lt;td&gt;ReadOnlyCollection&amp;lt;T&amp;gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td&gt;SortedList&lt;/td&gt;   &lt;td&gt;List&amp;lt;T&amp;gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td&gt;Stack&lt;/td&gt;   &lt;td&gt;Stack&amp;lt;T&amp;gt;&lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;Notice that in most of these cases you would have to figure out what the T is in the generic class. This assumes you used to store just one type of elements in your collection. If you are storing more than one type you should find the common base-class. In the worse case you can use Object but that would lose most of the benefits of generics.&lt;/p&gt;  &lt;p&gt;Let’s look at an example:&lt;/p&gt;  &lt;p&gt;This is the old code using non-generic Stack:&lt;/p&gt;  &lt;div style="border: 1px solid silver; padding: 10px; margin-left: 20px; color: black; font-family: 'Courier New',Courier,monospace; font-size: 10pt;"&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.Collections;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Stack&lt;/span&gt; MRUFiles = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Stack&lt;/span&gt;();&lt;/p&gt; &lt;p style="margin: 0px;"&gt;MRUFiles.Push(&lt;span style="color: rgb(163, 21, 21);"&gt;"first"&lt;/span&gt;);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;MRUFiles.Push(&lt;span style="color: rgb(163, 21, 21);"&gt;"second"&lt;/span&gt;);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;MRUFiles.Push(&lt;span style="color: rgb(163, 21, 21);"&gt;"third"&lt;/span&gt;);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(MRUFiles.Pop() &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;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(MRUFiles.Peek() &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;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(MRUFiles.Pop() &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;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(MRUFiles.Count.ToString());&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Same code would look like this using generic Stack&amp;lt;String&amp;gt;:&lt;/p&gt;  &lt;div style="border: 1px solid silver; padding: 10px; margin-left: 20px; color: black; font-family: 'Courier New',Courier,monospace; font-size: 10pt;"&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Stack&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&amp;gt; MRUFiles = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Stack&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&amp;gt;();&lt;/p&gt; &lt;p style="margin: 0px;"&gt;MRUFiles.Push(&lt;span style="color: rgb(163, 21, 21);"&gt;"first"&lt;/span&gt;);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;MRUFiles.Push(&lt;span style="color: rgb(163, 21, 21);"&gt;"second"&lt;/span&gt;);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;MRUFiles.Push(&lt;span style="color: rgb(163, 21, 21);"&gt;"third"&lt;/span&gt;);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(MRUFiles.Pop());&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(MRUFiles.Peek());&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(MRUFiles.Pop());&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(MRUFiles.Count.ToString());&lt;/p&gt; &lt;/div&gt;  &lt;h3&gt;Additional considerations when making the change:&lt;/h3&gt;  &lt;ol&gt; 	&lt;li&gt;List&amp;lt;Boolean&amp;gt; is not a good enough replacement for BitArray when it comes to the use of memory. If you have a list of millions of bits, using a BitArray would have a much smaller memory footprint than List&amp;lt;Boolean&amp;gt; since it’s actually manipulating bits instead of storing each bit as a Boolean that takes 8 bits each. In addition methods such as And, Xor, Not, Or and SetAll will not exist and you’d have to implement them yourself&lt;/li&gt; 	&lt;li&gt;Dictionary&amp;lt;K,V&amp;gt; indexer behaves differently than Hashtable did when the key is not found. With Hashtable you would get a null whereas with Dictionary you would get a KeyNotFoundException. So, you would probably have to alter your code a bit to catch this exception and add code to handle this case. Note that you can add a null element to the dictionary and still get null but in the case of Hashtable you would not know when you get a null if it’s a case of a missing key or a case of a null element. You can also call the TryGetValue method instead of using a try/catch block and check its return value.&lt;/li&gt; 	 	&lt;li&gt;ArrayList.Add() returns the index whereas List.Add returns void. If your legacy code used to rely on the return value you would have to slightly change it to get the index from Count — 1 since you know it’s always inserted last.&lt;/li&gt; 	&lt;li&gt;ArrayList.ToArray() calls required  not only providing the type but also casting the result to the appropriate array. For example: (String[]) m_list.ToArray(typeof(String)); with List&amp;lt;T&amp;gt; you don’t need to worry about this as it’s already in the correct type so you would have to change this to simply be m_list.ToArray();&lt;/li&gt; 	&lt;li&gt;If you are enumerating over a Hashtable you’ll have to change your code, here is an example: &lt;p&gt;&lt;u&gt;BEFORE&lt;/u&gt;&lt;/p&gt;  &lt;div style="border: 1px solid silver; padding: 10px; margin-left: 20px; color: black; font-family: 'Courier New',Courier,monospace; font-size: 10pt;"&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IDictionaryEnumerator&lt;/span&gt; de = m_Datastore.GetEnumerator();&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;while&lt;/span&gt; (de.MoveNext()) {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ilcc.Datastore[(&lt;span style="color: rgb(43, 145, 175);"&gt;String&lt;/span&gt;)de.Key] = de.Value;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;&lt;u&gt;AFTER&lt;/u&gt;&lt;/p&gt;  &lt;div style="border: 1px solid silver; padding: 10px; margin-left: 20px; color: black; font-family: 'Courier New',Courier,monospace; font-size: 10pt;"&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IEnumerator&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;String&lt;/span&gt;, &lt;span style="color: rgb(43, 145, 175);"&gt;Object&lt;/span&gt;&amp;gt;&amp;gt; de = m_Datastore.GetEnumerator();&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;while&lt;/span&gt; (de.MoveNext()) {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ilcc.Datastore[de.Current.Key] = de.Current.Value;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;/li&gt; 	&lt;li&gt;Threading/Synchronization issues:&lt;ol style="list-style-type: lower-alpha;"&gt; 		&lt;li&gt;Hashtable.Item property is multiple-reader/single-writer thread safe, but Dictionary’s getters are not. If your application has a dependency on the thread-safety guarantee of this Hashtable property, but you want to convert Hashtable to Dictionary, then you’ll need to handle this case explicitly&lt;/li&gt; 		&lt;li&gt;Whereas the non-generic collections offered a synchronized wrappers through their APIs — e.g. Hashtable.Synchronized—the generic collections don’t.&lt;/li&gt; 	&lt;/ol&gt; 	 	&lt;p&gt;If you want the quick “golden hammer” workaround to the thread safety issues, you can just lock on the SyncRoot of the Dictionary (after casting to ICollection), but this is most likely unnecessarily expensive for your app. But first we’ll first show the golden hammer technique. Note that wrapping every calls to Dictionary this way will perform the equivalent of Hashtable’s #7b behavior but is stronger than Hashtable’s #7a.&lt;/p&gt;  &lt;p&gt;&lt;u&gt;BEFORE&lt;/u&gt;&lt;/p&gt;  &lt;div style="border: 1px solid silver; padding: 10px; margin-left: 20px; color: black; font-family: 'Courier New',Courier,monospace; font-size: 10pt;"&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;String&lt;/span&gt; myKey = &lt;span style="color: rgb(163, 21, 21);"&gt;"key"&lt;/span&gt;;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;String&lt;/span&gt; myValue = &lt;span style="color: rgb(163, 21, 21);"&gt;"value"&lt;/span&gt;;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Hashtable&lt;/span&gt; myHashtable = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Hashtable&lt;/span&gt;();&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Hashtable&lt;/span&gt; mySynchronizedHashtable = &lt;span style="color: rgb(43, 145, 175);"&gt;Hashtable&lt;/span&gt;.Synchronized(myHashtable);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;myHashtable.Add(myKey, myValue);&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;&lt;u&gt;AFTER&lt;/u&gt;&lt;/p&gt;  &lt;div style="border: 1px solid silver; padding: 10px; margin-left: 20px; color: black; font-family: 'Courier New',Courier,monospace; font-size: 10pt;"&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;String&lt;/span&gt; myKey = &lt;span style="color: rgb(163, 21, 21);"&gt;"key"&lt;/span&gt;;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;String&lt;/span&gt; myValue = &lt;span style="color: rgb(163, 21, 21);"&gt;"value"&lt;/span&gt;;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;String&lt;/span&gt;, &lt;span style="color: rgb(43, 145, 175);"&gt;String&lt;/span&gt;&amp;gt; myDictionary = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;String&lt;/span&gt;, &lt;span style="color: rgb(43, 145, 175);"&gt;String&lt;/span&gt;&amp;gt;();&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;lock&lt;/span&gt; (((&lt;span style="color: rgb(43, 145, 175);"&gt;ICollection&lt;/span&gt;)myDictionary).SyncRoot) {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myDictionary.Add(myKey, myValue);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;The decision to remove the synchronized wrapped from generics was based on the observation that you often want to perform synchronization at a higher level in your application, and that our synchronized wrappers led to a false sense of security (and flawed code). This puts developers in the position of thinking more heavily about synchronization, but we decided this was the right call. This decision is discussed more thoroughly here: &lt;a href="http://blogs.msdn.com/bclteam/archive/2005/03/15/396399.aspx" mce_href="http://blogs.msdn.com/bclteam/archive/2005/03/15/396399.aspx"&gt;http://blogs.msdn.com/bclteam/archive/2005/03/15/396399.aspx&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;As mentioned above, the golden hammer workaround (used with all calls to Dictionary, including reads) is stronger than #7a. If you lock before every call, then you can have at most one reader or writer at a time. However, the Hashtable.Item property is single reader/multiple writer threadsafe. If you want this same behavior, you can use a ReaderWriterLock or, if you have Orcas installed, ReaderWriterLockSlim.&lt;/p&gt; &lt;p&gt;In general, the best decision for the #7 conversion will depend on the needs of your app: do you want multiple reader/single writer thread safety? Do you want to lock on the Dictionary SyncRoot or a different object, to coordinate accesses among the Dictionary and another collection (discussed in above-mentioned blog)? You can use our suggestions as starting points and customize depending on the needs of your app.&lt;/p&gt; 	 	&lt;/li&gt; &lt;/ol&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3531569" width="1" height="1"&gt;&lt;img alt="via softlogger.com" src="http://softlogger.com/postview.aspx?ArticleID=7223"&gt;</description><author>BCLTeams WebLog</author><pubDate>2007-06-25T00:00:00</pubDate><category>Object Oriented Concepts</category></item><item><title>LINQ To Objects - Part 3</title><link>http://softlogger.com/7111/Object-Oriented-Concepts/linq-to-objects--part-3.aspx</link><description>&lt;P&gt;&lt;FONT face=Verdana&gt;&amp;nbsp;&amp;nbsp;&lt;FONT size=2&gt; Although&lt;/FONT&gt; &lt;FONT size=2&gt;some of the queries we saw at the end of Part 2 are quite impressive - and light years easier than doing it with Loops and If/Then tests - there are still more improvements to come.&amp;nbsp;&amp;nbsp; Let's take the situation where you want to&lt;/FONT&gt; &lt;FONT size=2&gt;run Join queries&amp;nbsp;across two separate data sources.&amp;nbsp; This is&amp;nbsp;something you'll commonly do with Access or SQL Server, etc, data sources but not something you'd automatically think of doing with, for example, a couple of collections.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;&amp;nbsp;&amp;nbsp; To demonstrate this, we can use a collection of objects from the Person class that we created earlier, together with a new Class that contains a field or fields that we can join them on. The scenario I'm going to use is that we run courses in the UK and in Belgium, so we will have a class named "Course". Here is the code for that class: &lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: #800040 1px solid; BORDER-TOP: #800040 1px solid; MARGIN-LEFT: 10pt; BORDER-LEFT: #800040 1px solid; MARGIN-RIGHT: 2pt; BORDER-BOTTOM: #800040 1px solid"&gt;
&lt;DIV style="FONT-SIZE: 10pt; BORDER-BOTTOM: #800040 1px solid" onclick="var i=this.sel,j;if(i==this.selold)return;var sh=new Array('none',''),o=this.parentNode;j=i==0?0:1;this.selold=i;o.childNodes[1].style.display=sh[j];o.childNodes[2].style.display=sh[1-j];o=o.childNodes[1];var h =o.offsetHeight;o.style.height=i==1?'150pt':'';if(i==1 &amp;amp;&amp;amp; o.offsetHeight&gt;h)o.style.height=h;" selold="1" sel="1"&gt;&lt;B&gt;Code &lt;/B&gt;&lt;A onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');" href="javascript:"&gt;Copy &lt;/A&gt;&lt;INPUT onclick=parentNode.sel=0 type=button value=Hide&gt;&lt;INPUT onclick=parentNode.sel=1 type=button value=Scroll&gt;&lt;INPUT onclick=parentNode.sel=2 type=button value=Full&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 15px; OVERFLOW: auto; FONT-FAMILY: 'Courier New'; HEIGHT: 150px; BACKGROUND-COLOR: #ffffb7"&gt;&lt;FONT color=#0000ff&gt;Public&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Class&lt;/FONT&gt; Course&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Private&lt;/FONT&gt; m_Title&lt;FONT color=#0000ff&gt; As&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; String&lt;/FONT&gt; =&lt;FONT color=#a31515&gt; "Not Known"&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Private&lt;/FONT&gt; m_Location&lt;FONT color=#0000ff&gt; As&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; String&lt;/FONT&gt; =&lt;FONT color=#a31515&gt; "Not Known"&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Private&lt;/FONT&gt; m_StartDate&lt;FONT color=#0000ff&gt; As&lt;/FONT&gt; DateTime = Today&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Private&lt;/FONT&gt; m_DurationDays&lt;FONT color=#0000ff&gt; As&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Integer&lt;/FONT&gt; = 1&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Property&lt;/FONT&gt; Title()&lt;FONT color=#0000ff&gt; As&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; String&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Get&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Return&lt;/FONT&gt; m_Title&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Get&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set&lt;/FONT&gt;(&lt;FONT color=#0000ff&gt;ByVal&lt;/FONT&gt; value&lt;FONT color=#0000ff&gt; As&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; String&lt;/FONT&gt;)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_Title = value&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Set&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Property&lt;BR&gt;&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Property&lt;/FONT&gt; Location()&lt;FONT color=#0000ff&gt; As&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; String&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Get&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Return&lt;/FONT&gt; m_Location&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Get&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set&lt;/FONT&gt;(&lt;FONT color=#0000ff&gt;ByVal&lt;/FONT&gt; value&lt;FONT color=#0000ff&gt; As&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; String&lt;/FONT&gt;)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_Location = value&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Set&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Property&lt;BR&gt;&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Property&lt;/FONT&gt; StartDate()&lt;FONT color=#0000ff&gt; As&lt;/FONT&gt; DateTime&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Get&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Return&lt;/FONT&gt; m_StartDate&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Get&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set&lt;/FONT&gt;(&lt;FONT color=#0000ff&gt;ByVal&lt;/FONT&gt; value&lt;FONT color=#0000ff&gt; As&lt;/FONT&gt; DateTime)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_StartDate = value&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Set&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Property&lt;BR&gt;&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Property&lt;/FONT&gt; DurationDays()&lt;FONT color=#0000ff&gt; As&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Integer&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Get&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Return&lt;/FONT&gt; m_DurationDays&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Get&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set&lt;/FONT&gt;(&lt;FONT color=#0000ff&gt;ByVal&lt;/FONT&gt; value&lt;FONT color=#0000ff&gt; As&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Integer&lt;/FONT&gt;)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_DurationDays = value&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Set&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Property&lt;BR&gt;&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Public&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Overrides&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Function&lt;/FONT&gt; ToString()&lt;FONT color=#0000ff&gt; As&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; String&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Return&lt;/FONT&gt; m_Title &amp;amp;&lt;FONT color=#a31515&gt; " : "&lt;/FONT&gt; &amp;amp; m_Location&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Function&lt;BR&gt;&lt;BR&gt;End&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Class&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV style="DISPLAY: none; BACKGROUND-COLOR: #ffffb7"&gt;&lt;B&gt;. . .&lt;/B&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;And, as I'm sure you'll realise, we will use the Location Property in the Course class as the field to join the HomeTown property of the Person class - the purpose of this imaginary scenario being that we can invite potential students to attend courses in their home town.&lt;/P&gt;
&lt;P&gt;As we did in earlier examples for the Person class, we can create a simple array of Course objects:&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: #800040 1px solid; BORDER-TOP: #800040 1px solid; MARGIN-LEFT: 10pt; BORDER-LEFT: #800040 1px solid; MARGIN-RIGHT: 2pt; BORDER-BOTTOM: #800040 1px solid"&gt;
&lt;DIV style="FONT-SIZE: 10pt; BORDER-BOTTOM: #800040 1px solid" onclick="var i=this.sel,j;if(i==this.selold)return;var sh=new Array('none',''),o=this.parentNode;j=i==0?0:1;this.selold=i;o.childNodes[1].style.display=sh[j];o.childNodes[2].style.display=sh[1-j];o=o.childNodes[1];var h =o.offsetHeight;o.style.height=i==1?'150pt':'';if(i==1 &amp;amp;&amp;amp; o.offsetHeight&gt;h)o.style.height=h;" selold="2" sel="2"&gt;&lt;B&gt;Code &lt;/B&gt;&lt;A onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');" href="javascript:"&gt;Copy &lt;/A&gt;&lt;INPUT onclick=parentNode.sel=0 type=button value=Hide&gt;&lt;INPUT onclick=parentNode.sel=1 type=button value=Scroll&gt;&lt;INPUT onclick=parentNode.sel=2 type=button value=Full&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 15px; OVERFLOW: auto; FONT-FAMILY: 'Courier New'; BACKGROUND-COLOR: #ffffb7"&gt;&lt;FONT color=#0000ff&gt;Function&lt;/FONT&gt; CreateCourses()&lt;FONT color=#0000ff&gt; As&lt;/FONT&gt; Array&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&lt;/FONT&gt; SomeCourses()&lt;FONT color=#0000ff&gt; As&lt;/FONT&gt; Course = {&lt;FONT color=#0000ff&gt;New&lt;/FONT&gt; Course&lt;FONT color=#0000ff&gt; With&lt;/FONT&gt; {.Title =&lt;FONT color=#a31515&gt; "VB 2005"&lt;/FONT&gt;, _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.Location =&lt;FONT color=#a31515&gt; "Leeds"&lt;/FONT&gt;, .StartDate =&lt;FONT color=#0000ff&gt; New&lt;/FONT&gt; DateTime(2007, 8, 8), .DurationDays = 7}, _&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;New&lt;/FONT&gt; Course&lt;FONT color=#0000ff&gt; With&lt;/FONT&gt; {.Title =&lt;FONT color=#a31515&gt; "Java"&lt;/FONT&gt;, .Location =&lt;FONT color=#a31515&gt; "Ghent"&lt;/FONT&gt;, .StartDate =&lt;FONT color=#0000ff&gt; New&lt;/FONT&gt; DateTime(2007, 12, 1), _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.DurationDays = 14}, _&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;New&lt;/FONT&gt; Course&lt;FONT color=#0000ff&gt; With&lt;/FONT&gt; {.Title =&lt;FONT color=#a31515&gt; "Ajax"&lt;/FONT&gt;, .Location =&lt;FONT color=#a31515&gt; "Manchester"&lt;/FONT&gt;, .StartDate =&lt;FONT color=#0000ff&gt; New&lt;/FONT&gt; DateTime(2008, 1, 13), _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.DurationDays = 10}, _&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;New&lt;/FONT&gt; Course&lt;FONT color=#0000ff&gt; With&lt;/FONT&gt; {.Title =&lt;FONT color=#a31515&gt; "Classic VB"&lt;/FONT&gt;, .Location =&lt;FONT color=#a31515&gt; "Leeds"&lt;/FONT&gt;, .StartDate =&lt;FONT color=#0000ff&gt; New&lt;/FONT&gt; DateTime(2006, 2, 2), _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.DurationDays = 10}, _&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;New&lt;/FONT&gt; Course&lt;FONT color=#0000ff&gt; With&lt;/FONT&gt; {.Title =&lt;FONT color=#a31515&gt; "SQL Server 2005"&lt;/FONT&gt;, .StartDate =&lt;FONT color=#0000ff&gt; New&lt;/FONT&gt; DateTime(2008, 5, 6), _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.Location =&lt;FONT color=#a31515&gt; "London"&lt;/FONT&gt;, .DurationDays = 12}}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Return&lt;/FONT&gt; SomeCourses&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Function&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV style="DISPLAY: none; BACKGROUND-COLOR: #ffffb7"&gt;&lt;B&gt;. . .&lt;/B&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp; Note that for demo purposes I've included a course location in London, a place which none of our current Persons have their HomeTown, and also a course start date which has already passed.&amp;nbsp;&amp;nbsp; We can use these&amp;nbsp;for validation purposes in our queries.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp; First, we need to create the two arrays to query on:&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: #800040 1px solid; BORDER-TOP: #800040 1px solid; MARGIN-LEFT: 10pt; BORDER-LEFT: #800040 1px solid; MARGIN-RIGHT: 2pt; BORDER-BOTTOM: #800040 1px solid"&gt;
&lt;DIV style="FONT-SIZE: 10pt; BORDER-BOTTOM: #800040 1px solid"&gt;&lt;B&gt;Code &lt;/B&gt;&lt;A onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');" href="javascript:"&gt;Copy &lt;/A&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 15px; OVERFLOW: auto; FONT-FAMILY: 'Courier New'; BACKGROUND-COLOR: #ffffb7"&gt;&lt;FONT color=#0000ff&gt;Public&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Class&lt;/FONT&gt; Form1&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&lt;/FONT&gt; People()&lt;FONT color=#0000ff&gt; As&lt;/FONT&gt; Person&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&lt;/FONT&gt; Courses()&lt;FONT color=#0000ff&gt; As&lt;/FONT&gt; Course&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Private&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Sub&lt;/FONT&gt; Form1_Load(&lt;FONT color=#0000ff&gt;ByVal&lt;/FONT&gt; sender&lt;FONT color=#0000ff&gt; As&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Object&lt;/FONT&gt;,&lt;FONT color=#0000ff&gt; ByVal&lt;/FONT&gt; e&lt;FONT color=#0000ff&gt; As&lt;/FONT&gt; System.EventArgs)&lt;FONT color=#0000ff&gt; Handles&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Me&lt;/FONT&gt;.Load&lt;BR&gt;&lt;FONT color=#008000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;'&amp;nbsp;&amp;nbsp;Get some data to work with&lt;/FONT&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;People = CreateDataVB9_3()&lt;FONT color=#008000&gt;&lt;/FONT&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Courses = CreateCourses()&lt;FONT color=#0000ff&gt;&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; Sub&lt;/FONT&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;And then we can run a query that matches all Persons whose HomeTowns are located in a place where we hold a course (reagrdless of course date): &lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: #800040 1px solid; BORDER-TOP: #800040 1px solid; MARGIN-LEFT: 10pt; BORDER-LEFT: #800040 1px solid; MARGIN-RIGHT: 2pt; BORDER-BOTTOM: #800040 1px solid"&gt;
&lt;DIV style="FONT-SIZE: 10pt; BORDER-BOTTOM: #800040 1px solid"&gt;&lt;B&gt;Code &lt;/B&gt;&lt;A onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');" href="javascript:"&gt;Copy &lt;/