<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>OOP - There It Is - 2.0</title>
    <link>http://www.vpsw.com/blogbaby/</link>
    <description>A Very Practical Blog</description>
    <language>en-us</language>
    <copyright>Dean Fiala</copyright>
    <lastBuildDate>Wed, 11 Jun 2008 03:24:01 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.1.8102.813</generator>
    <managingEditor>dfiala@vpsw.com</managingEditor>
    <webMaster>dfiala@vpsw.com</webMaster>
    <item>
      <trackback:ping>http://www.vpsw.com/blogbaby/Trackback.aspx?guid=5ebf2926-8003-4c16-b328-8e91755317b0</trackback:ping>
      <pingback:server>http://www.vpsw.com/blogbaby/pingback.aspx</pingback:server>
      <pingback:target>http://www.vpsw.com/blogbaby/PermaLink,guid,5ebf2926-8003-4c16-b328-8e91755317b0.aspx</pingback:target>
      <dc:creator>Dean</dc:creator>
      <wfw:comment>http://www.vpsw.com/blogbaby/CommentView,guid,5ebf2926-8003-4c16-b328-8e91755317b0.aspx</wfw:comment>
      <wfw:commentRss>http://www.vpsw.com/blogbaby/SyndicationService.asmx/GetEntryCommentsRss?guid=5ebf2926-8003-4c16-b328-8e91755317b0</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The Resharper cult members already know this, but for those who haven't joined yet,
version <a href="http://www.jetbrains.com/resharper/download/">4.0 released today</a> with
VS 2008 support -- huzzah,  huzzah.  No longer able to resist the chanting
and promises of eternal coolness I donned my robe and installed my free copy.
</p>
        <p>
I clearly should have joined sooner.  Resharper has already changed my life. 
First it pointed that I had redundant overrides  in the control I was working
on, which I had really meant to delete. 
</p>
        <p>
Then it reminded me about the new <a href="http://msdn.microsoft.com/en-us/library/bb384061.aspx">implicit
type declaration</a> keyword var, so this...
</p>
        <blockquote>
          <p>
            <font face="Courier New" color="#0000ff">XmlDocument SomeDoc = new XmlDocument();</font>
          </p>
        </blockquote>
        <p>
becomes...
</p>
        <blockquote>
          <p>
            <font face="Courier New" color="#0000ff">var SomeDoc = new XmlDocument();</font>
          </p>
        </blockquote>
        <p>
Granted, that's not too exciting, but if your type declaration is something like...
</p>
        <blockquote>
          <font face="Courier New" color="#0000ff">Dictionary&lt;SomeStrangeType,ANamespace.AnotherLongType&gt;
SomeDictionary = new Dictionary&lt;SomeStrangeType,ANamespace.AnotherLongType&gt;();</font>
        </blockquote>
        <p>
with var it becomes...
</p>
        <blockquote>
          <p>
            <font face="Courier New" color="#0000ff">var SomeDictionary = new Dictionary&lt;SomeStrangeType,ANamespace.AnotherLongType&gt;();</font>
          </p>
        </blockquote>
        <p>
Then Resharper pointed out something I didn't realize was available in C#, the <a href="http://msdn.microsoft.com/en-us/library/bb384062.aspx">object
intializer</a>?? VB.NET has long had something similar with the <a href="http://msdn.microsoft.com/en-us/library/wc500chb.aspx">With
statement</a> (now with <a href="http://msdn.microsoft.com/en-us/library/bb385125.aspx">object
initializer goodness</a> too).  What's nice about this is that it saves repeating
the instance name in front of the properties.  So this...
</p>
        <blockquote>
          <p>
            <font face="Courier New" color="#0000ff">var MenuBinding = new MenuItemBinding(); 
<br />
MenuBinding.DataMember = MenuItemElementName; 
<br />
MenuBinding.TextField = DisplayTextAttribute; 
<br />
MenuBinding.NavigateUrlField = NavigationUrlAttribute; 
<br />
MenuBinding.Depth = Depth;</font>
          </p>
        </blockquote>
        <p>
becomes...
</p>
        <blockquote>
          <p>
            <font face="Courier New" color="#0000ff">var MenuBinding = new MenuItemBinding 
<br />
  { 
<br />
     DataMember = MenuItemElementName, 
<br />
     TextField = DisplayTextAttribute, 
<br />
     NavigateUrlField = NavigationUrlAttribute, 
<br />
     Depth = Depth 
<br />
  };</font>
          </p>
        </blockquote>
        <p>
I was staring at this new construct when I realized that -- it shouldn't work. The
project I was working on was a Framework 2.0 project and these things were in 3.0
syntax.  But the darn thing compiles and works.  Not even a single warning. 
WTF?  It turns out that since 3.0 and 3.5 are based on 2.0, these are simply
compiler tricks -- there is nothing fundamentally different about the types. 
Here's a <a href="http://weblogs.asp.net/shahar/archive/2008/01/23/use-c-3-features-from-c-2-and-net-2-0-code.aspx">blog
post</a> that explores in more detail what is happening under the covers.
</p>
        <p>
Not bad for 15 minutes of tooling around.  Guess I am an official member. Where's
the Koolaid?
</p>
        <img width="0" height="0" src="http://www.vpsw.com/blogbaby/aggbug.ashx?id=5ebf2926-8003-4c16-b328-8e91755317b0" />
      </body>
      <title>Sharpening Knives</title>
      <guid isPermaLink="false">http://www.vpsw.com/blogbaby/PermaLink,guid,5ebf2926-8003-4c16-b328-8e91755317b0.aspx</guid>
      <link>http://www.vpsw.com/blogbaby/PermaLink,guid,5ebf2926-8003-4c16-b328-8e91755317b0.aspx</link>
      <pubDate>Wed, 11 Jun 2008 03:24:01 GMT</pubDate>
      <description>&lt;p&gt;
The Resharper cult members already know this, but for those who haven't joined yet,
version &lt;a href="http://www.jetbrains.com/resharper/download/"&gt;4.0 released today&lt;/a&gt; with
VS 2008 support -- huzzah,&amp;#160; huzzah.&amp;#160; No longer able to resist the chanting
and promises of eternal coolness I donned my robe and installed my free copy.
&lt;/p&gt;
&lt;p&gt;
I clearly should have joined sooner.&amp;#160; Resharper has already changed my life.&amp;#160;
First it pointed that I had redundant overrides&amp;#160; in the control I was working
on, which I had really meant to delete. 
&lt;/p&gt;
&lt;p&gt;
Then it reminded me about the new &lt;a href="http://msdn.microsoft.com/en-us/library/bb384061.aspx"&gt;implicit
type declaration&lt;/a&gt; keyword var, so this...
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;font face="Courier New" color="#0000ff"&gt;XmlDocument SomeDoc = new XmlDocument();&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
becomes...
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;font face="Courier New" color="#0000ff"&gt;var SomeDoc = new XmlDocument();&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Granted, that's not too exciting, but if your type declaration is something like...
&lt;/p&gt;
&lt;blockquote&gt;&lt;font face="Courier New" color="#0000ff"&gt;Dictionary&amp;lt;SomeStrangeType,ANamespace.AnotherLongType&amp;gt;
SomeDictionary = new Dictionary&amp;lt;SomeStrangeType,ANamespace.AnotherLongType&amp;gt;();&lt;/font&gt; &lt;/blockquote&gt; 
&lt;p&gt;
with var it becomes...
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;font face="Courier New" color="#0000ff"&gt;var SomeDictionary = new Dictionary&amp;lt;SomeStrangeType,ANamespace.AnotherLongType&amp;gt;();&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Then Resharper pointed out something I didn't realize was available in C#, the &lt;a href="http://msdn.microsoft.com/en-us/library/bb384062.aspx"&gt;object
intializer&lt;/a&gt;?? VB.NET has long had something similar with the &lt;a href="http://msdn.microsoft.com/en-us/library/wc500chb.aspx"&gt;With
statement&lt;/a&gt; (now with &lt;a href="http://msdn.microsoft.com/en-us/library/bb385125.aspx"&gt;object
initializer goodness&lt;/a&gt; too).&amp;#160; What's nice about this is that it saves repeating
the instance name in front of the properties.&amp;#160; So this...
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;font face="Courier New" color="#0000ff"&gt;var MenuBinding = new MenuItemBinding(); 
&lt;br /&gt;
MenuBinding.DataMember = MenuItemElementName; 
&lt;br /&gt;
MenuBinding.TextField = DisplayTextAttribute; 
&lt;br /&gt;
MenuBinding.NavigateUrlField = NavigationUrlAttribute; 
&lt;br /&gt;
MenuBinding.Depth = Depth;&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
becomes...
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;font face="Courier New" color="#0000ff"&gt;var MenuBinding = new MenuItemBinding 
&lt;br /&gt;
&amp;#160; { 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160; DataMember = MenuItemElementName, 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160; TextField = DisplayTextAttribute, 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160; NavigateUrlField = NavigationUrlAttribute, 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160; Depth = Depth 
&lt;br /&gt;
&amp;#160; };&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
I was staring at this new construct when I realized that -- it shouldn't work. The
project I was working on was a Framework 2.0 project and these things were in 3.0
syntax.&amp;#160; But the darn thing compiles and works.&amp;#160; Not even a single warning.&amp;#160;
WTF?&amp;#160; It turns out that since 3.0 and 3.5 are based on 2.0, these are simply
compiler tricks -- there is nothing fundamentally different about the types.&amp;#160;
Here's a &lt;a href="http://weblogs.asp.net/shahar/archive/2008/01/23/use-c-3-features-from-c-2-and-net-2-0-code.aspx"&gt;blog
post&lt;/a&gt; that explores in more detail what is happening under the covers.
&lt;/p&gt;
&lt;p&gt;
Not bad for 15 minutes of tooling around.&amp;#160; Guess I am an official member. Where's
the Koolaid?
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.vpsw.com/blogbaby/aggbug.ashx?id=5ebf2926-8003-4c16-b328-8e91755317b0" /&gt;</description>
      <comments>http://www.vpsw.com/blogbaby/CommentView,guid,5ebf2926-8003-4c16-b328-8e91755317b0.aspx</comments>
      <category>.NET</category>
      <category>2.0</category>
      <category>3.0</category>
      <category>3.5</category>
      <category>Resharper</category>
    </item>
    <item>
      <trackback:ping>http://www.vpsw.com/blogbaby/Trackback.aspx?guid=5d2f79e5-0c0b-4b18-8439-ea11f8b871dc</trackback:ping>
      <pingback:server>http://www.vpsw.com/blogbaby/pingback.aspx</pingback:server>
      <pingback:target>http://www.vpsw.com/blogbaby/PermaLink,guid,5d2f79e5-0c0b-4b18-8439-ea11f8b871dc.aspx</pingback:target>
      <dc:creator>Dean</dc:creator>
      <wfw:comment>http://www.vpsw.com/blogbaby/CommentView,guid,5d2f79e5-0c0b-4b18-8439-ea11f8b871dc.aspx</wfw:comment>
      <wfw:commentRss>http://www.vpsw.com/blogbaby/SyndicationService.asmx/GetEntryCommentsRss?guid=5d2f79e5-0c0b-4b18-8439-ea11f8b871dc</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">Headaches.  Homicidal thoughts. 
Horrible alliterations.<br /><br />
All these things happened over the the last few days. 
<br /><br />
It all started when I needed to build 64-bit versions of a few .NET 2.0 apps (a wep
app, a windows service and a passel of supporting libraries).  This is actually
very simple to do. Visual Studio exposes a platform setting in the build configuration
for each project.  The default platform is anycpu.  Specifying x64 sets
the compiler option and instructs VS to build a 64-bit image (even on a 32-bit machine). 
Of course, doing this for a bunch of projects would be dull.  Fortunately, I
already have NANT scripts to build everything, so I added a platform parameter to
the compiler tasks and voila, a slew of 64-bit assemblies in 194 seconds. 
<br /><br />
Dropped the gooey mess on the 64-bit machine, and by gosh the web app worked and so
did the service.  Double checked that the 64-bit system was not running any 32-bit
assembly in <a href="http://support.microsoft.com/kb/896456">WOW</a> mode. Nope, all
64-bit baby!  Ran the applications through their paces, and they ran perfectly. 
.NET makes 64-bit apps happen with the flick of a (compiler) switch -- sweet!<br /><br />
Time to build the 64-bit installers for the web app and the service. Now, if 32-bit
deployment projects are the 3-eyed, 9-toed, humpbacked, perpetually sniffing step-chilldren
of .NET -- and they are -- 64-bit deployment projects make them look like the fairhaired,
first born heirs to the kingdom.  
<br /><br />
Just like any other app, deployment apps can be simply targeted to either platform. 
But finding the toggle is bit confusing.  It is not in the same place as "normal"
applications.  The platform can't be changed in the build configuration, you
must select the Installer in the Solution Explorer and click F4 to expose the properties. 
Selecting Properties... in the context menu for the installer does NOT expose the
same set of properties.  OK, a little swearing later, and the web app installer
is set to x64 bit and it builds the MSI. Woo hoo, looking good!<br /><br />
Time to test it on the x64 server.  An exception!  Ugghh.  BadFileImageFormat.  <a href="http://thedailywtf.com/">WTF</a>. 
Documentation time.  The error says I am trying to run a 64-bit image on a 32-bit
platform, but, but, but, I'm running a 64-bit image on 64-bit platform.  Some
googling, some double checking that a 32-bit assembly hadn't somehow screwed up the
MSI.  More swearing. Finally stumbled across this <a href="http://blogs.msdn.com/heaths/archive/2006/02/01/64-bit-managed-custom-actions-with-visual-studio.aspx">blog
post</a> which pointed me in the right direction. 
<br /><br />
The cause turned out to be a <a href="http://msdn2.microsoft.com/en-us/library/aa368066.aspx">Custom
Action</a> that updates the web.config file, sets some directory permissions and sets
up the application in IIS. The Custom Action is an installer class that is kicked
off by InstallUtil in the MSI.  Worked fine in 32-bit.  But, VS embeds the
32-bit version of InstallUtil in the MSI, even when a x64 platform has been targeted,
hence the BadFileImageFormat exception.  
<br /><br />
The workaround required downloading the Platform SDK and installing a tool named <a href="http://msdn2.microsoft.com/en-us/library/aa370557.aspx">Orca</a>. 
Orca lets you inspect/alter the MSI guts.  Pulled the 64-bit version of InstallUtil
from the x64 box and sucked it into the MSI using Orca. Saved the MSI and tried it
again. And behold it worked, Custom Action and all. Thank you <strike>Chuck Norris</strike> Heath
Stewart.<br /><br />
The service was bit trickier. I kept getting FileNotFound exceptions in the Windows
directory. But I wasn't trying to install anything in the Windows directory, which
was a bit perplexing.  The problem turned out to be the default directory for
installing the service had a space in it.  Yes, in 2008, this is still an issue.
Changed the default directory to something without spaces, and got around this error
only to run into the dreaded <b>InstallUtilLib.dll: Unknown Error., (NULL), (NULL),
(NULL)</b>.  More swearing.  Well, it turns out that InstallUtil doesn't
deal well with the way the installer package escapes path names when sending <a href="http://msdn2.microsoft.com/en-us/library/2w2fhwzz%28vs.71%29.aspx">data
to the Custom Action</a>.  So I just sent all the properties without the surrounding
quotes (since I was no longer allowing paths with spaces anyway) and the darn thing
finally worked.<br /><br />
There's got be a better way, the whole MSI process is so cobbled together, it is astounding
that anyone can create a usable installer without third party tools (and even they
seem hobbled by the Windows Installer determined quirkiness) or weeks of free time. 
<br /><br />
Now, all of this could have been avoided if I hadn't used Custom Actions.  But
there are no Standard Actions for:<br /><ul><li>
setting directory or file permissions</li><li>
setting up virtual directories in IIS<br /></li><li>
setting the ASP.NET version and application pool<br /></li><li>
updating configuration files</li></ul><br />
Also, the VS deployment project relies on a Custom Action to install the service,
instead of creating a service table in the MSI.  Not sure why this is, but tis
annoying to know it's there yet not exposed in the deployment project. If I had wanted
to dive into Orca, I could have used to it set up the table in the MSI, but my patience
had long since expired.<br /><br />
I'm not holding any hope that the situation will improve in the future.  As the
software world becomes ever more web-centered, there is even less call for building
installers.  With FTP and Xcopy it's easy enough to deploy web apps. Setting
up an app in IIS manually is trivial and .NET removes most of the need for dealing
with Registry foo. 
<br /><br />
If I have a client ask for install package again, I'm giving them a zip file and a
page of instructions.  Infinitely quicker than dealing with Misfit Solution Installers.<br /><p></p><img width="0" height="0" src="http://www.vpsw.com/blogbaby/aggbug.ashx?id=5d2f79e5-0c0b-4b18-8439-ea11f8b871dc" /></body>
      <title>You Go 64-bits And Whatya Get?</title>
      <guid isPermaLink="false">http://www.vpsw.com/blogbaby/PermaLink,guid,5d2f79e5-0c0b-4b18-8439-ea11f8b871dc.aspx</guid>
      <link>http://www.vpsw.com/blogbaby/PermaLink,guid,5d2f79e5-0c0b-4b18-8439-ea11f8b871dc.aspx</link>
      <pubDate>Wed, 09 Jan 2008 05:05:38 GMT</pubDate>
      <description>Headaches.&amp;nbsp; Homicidal thoughts.&amp;nbsp; Horrible alliterations.&lt;br&gt;
&lt;br&gt;
All these things happened over the the last few days. 
&lt;br&gt;
&lt;br&gt;
It all started when I needed to build 64-bit versions of a few .NET 2.0 apps (a wep
app, a windows service and a passel of supporting libraries).&amp;nbsp; This is actually
very simple to do. Visual Studio exposes a platform setting in the build configuration
for each project.&amp;nbsp; The default platform is anycpu.&amp;nbsp; Specifying x64 sets
the compiler option and instructs VS to build a 64-bit image (even on a 32-bit machine).&amp;nbsp;
Of course, doing this for a bunch of projects would be dull.&amp;nbsp; Fortunately, I
already have NANT scripts to build everything, so I added a platform parameter to
the compiler tasks and voila, a slew of 64-bit assemblies in 194 seconds. 
&lt;br&gt;
&lt;br&gt;
Dropped the gooey mess on the 64-bit machine, and by gosh the web app worked and so
did the service.&amp;nbsp; Double checked that the 64-bit system was not running any 32-bit
assembly in &lt;a href="http://support.microsoft.com/kb/896456"&gt;WOW&lt;/a&gt; mode. Nope, all
64-bit baby!&amp;nbsp; Ran the applications through their paces, and they ran perfectly.&amp;nbsp;
.NET makes 64-bit apps happen with the flick of a (compiler) switch -- sweet!&lt;br&gt;
&lt;br&gt;
Time to build the 64-bit installers for the web app and the service. Now, if 32-bit
deployment projects are the 3-eyed, 9-toed, humpbacked, perpetually sniffing step-chilldren
of .NET -- and they are -- 64-bit deployment projects make them look like the fairhaired,
first born heirs to the kingdom.&amp;nbsp; 
&lt;br&gt;
&lt;br&gt;
Just like any other app, deployment apps can be simply targeted to either platform.&amp;nbsp;
But finding the toggle is bit confusing.&amp;nbsp; It is not in the same place as "normal"
applications.&amp;nbsp; The platform can't be changed in the build configuration, you
must select the Installer in the Solution Explorer and click F4 to expose the properties.&amp;nbsp;
Selecting Properties... in the context menu for the installer does NOT expose the
same set of properties.&amp;nbsp; OK, a little swearing later, and the web app installer
is set to x64 bit and it builds the MSI. Woo hoo, looking good!&lt;br&gt;
&lt;br&gt;
Time to test it on the x64 server.&amp;nbsp; An exception!&amp;nbsp; Ugghh.&amp;nbsp; BadFileImageFormat.&amp;nbsp; &lt;a href="http://thedailywtf.com/"&gt;WTF&lt;/a&gt;.&amp;nbsp;
Documentation time.&amp;nbsp; The error says I am trying to run a 64-bit image on a 32-bit
platform, but, but, but, I'm running a 64-bit image on 64-bit platform.&amp;nbsp; Some
googling, some double checking that a 32-bit assembly hadn't somehow screwed up the
MSI.&amp;nbsp; More swearing. Finally stumbled across this &lt;a href="http://blogs.msdn.com/heaths/archive/2006/02/01/64-bit-managed-custom-actions-with-visual-studio.aspx"&gt;blog
post&lt;/a&gt; which pointed me in the right direction. 
&lt;br&gt;
&lt;br&gt;
The cause turned out to be a &lt;a href="http://msdn2.microsoft.com/en-us/library/aa368066.aspx"&gt;Custom
Action&lt;/a&gt; that updates the web.config file, sets some directory permissions and sets
up the application in IIS. The Custom Action is an installer class that is kicked
off by InstallUtil in the MSI.&amp;nbsp; Worked fine in 32-bit.&amp;nbsp; But, VS embeds the
32-bit version of InstallUtil in the MSI, even when a x64 platform has been targeted,
hence the BadFileImageFormat exception.&amp;nbsp; 
&lt;br&gt;
&lt;br&gt;
The workaround required downloading the Platform SDK and installing a tool named &lt;a href="http://msdn2.microsoft.com/en-us/library/aa370557.aspx"&gt;Orca&lt;/a&gt;.&amp;nbsp;
Orca lets you inspect/alter the MSI guts.&amp;nbsp; Pulled the 64-bit version of InstallUtil
from the x64 box and sucked it into the MSI using Orca. Saved the MSI and tried it
again. And behold it worked, Custom Action and all. Thank you &lt;strike&gt;Chuck Norris&lt;/strike&gt; Heath
Stewart.&lt;br&gt;
&lt;br&gt;
The service was bit trickier. I kept getting FileNotFound exceptions in the Windows
directory. But I wasn't trying to install anything in the Windows directory, which
was a bit perplexing.&amp;nbsp; The problem turned out to be the default directory for
installing the service had a space in it.&amp;nbsp; Yes, in 2008, this is still an issue.
Changed the default directory to something without spaces, and got around this error
only to run into the dreaded &lt;b&gt;InstallUtilLib.dll: Unknown Error., (NULL), (NULL),
(NULL)&lt;/b&gt;.&amp;nbsp; More swearing.&amp;nbsp; Well, it turns out that InstallUtil doesn't
deal well with the way the installer package escapes path names when sending &lt;a href="http://msdn2.microsoft.com/en-us/library/2w2fhwzz%28vs.71%29.aspx"&gt;data
to the Custom Action&lt;/a&gt;.&amp;nbsp; So I just sent all the properties without the surrounding
quotes (since I was no longer allowing paths with spaces anyway) and the darn thing
finally worked.&lt;br&gt;
&lt;br&gt;
There's got be a better way, the whole MSI process is so cobbled together, it is astounding
that anyone can create a usable installer without third party tools (and even they
seem hobbled by the Windows Installer determined quirkiness) or weeks of free time. 
&lt;br&gt;
&lt;br&gt;
Now, all of this could have been avoided if I hadn't used Custom Actions.&amp;nbsp; But
there are no Standard Actions for:&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;
setting directory or file permissions&lt;/li&gt;
&lt;li&gt;
setting up virtual directories in IIS&lt;br&gt;
&lt;/li&gt;
&lt;li&gt;
setting the ASP.NET version and application pool&lt;br&gt;
&lt;/li&gt;
&lt;li&gt;
updating configuration files&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
Also, the VS deployment project relies on a Custom Action to install the service,
instead of creating a service table in the MSI.&amp;nbsp; Not sure why this is, but tis
annoying to know it's there yet not exposed in the deployment project. If I had wanted
to dive into Orca, I could have used to it set up the table in the MSI, but my patience
had long since expired.&lt;br&gt;
&lt;br&gt;
I'm not holding any hope that the situation will improve in the future.&amp;nbsp; As the
software world becomes ever more web-centered, there is even less call for building
installers.&amp;nbsp; With FTP and Xcopy it's easy enough to deploy web apps. Setting
up an app in IIS manually is trivial and .NET removes most of the need for dealing
with Registry foo. 
&lt;br&gt;
&lt;br&gt;
If I have a client ask for install package again, I'm giving them a zip file and a
page of instructions.&amp;nbsp; Infinitely quicker than dealing with Misfit Solution Installers.&lt;br&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.vpsw.com/blogbaby/aggbug.ashx?id=5d2f79e5-0c0b-4b18-8439-ea11f8b871dc" /&gt;</description>
      <comments>http://www.vpsw.com/blogbaby/CommentView,guid,5d2f79e5-0c0b-4b18-8439-ea11f8b871dc.aspx</comments>
      <category>2.0</category>
      <category>64-bit</category>
    </item>
    <item>
      <trackback:ping>http://www.vpsw.com/blogbaby/Trackback.aspx?guid=b187e79b-18a4-4edc-a0e8-61932ac53ae3</trackback:ping>
      <pingback:server>http://www.vpsw.com/blogbaby/pingback.aspx</pingback:server>
      <pingback:target>http://www.vpsw.com/blogbaby/PermaLink,guid,b187e79b-18a4-4edc-a0e8-61932ac53ae3.aspx</pingback:target>
      <dc:creator>Dean</dc:creator>
      <wfw:comment>http://www.vpsw.com/blogbaby/CommentView,guid,b187e79b-18a4-4edc-a0e8-61932ac53ae3.aspx</wfw:comment>
      <wfw:commentRss>http://www.vpsw.com/blogbaby/SyndicationService.asmx/GetEntryCommentsRss?guid=b187e79b-18a4-4edc-a0e8-61932ac53ae3</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">I went on vacation at the end of July and
returned in early August. Life restarted in fits and starts.  But somehow I neglected
to get this blog started again. Now that five months have passed, I think it is time
to begin again.  So without further ado...<br /><br />
Had a question on a forum today about how to access the top master page if you are
using nested master pages.  Seemed like a good time to break out some recursion.  
<br /><br /><blockquote><font color="#000080" face="Courier New">protected MasterPage UltimateMaster(Page
ThePage)</font><font color="#000080"><br /></font><font color="#000080" face="Courier New">{</font><font color="#000080"><br /></font><font color="#000080" face="Courier New">      if
(ThePage.Master == null)</font><font color="#000080"><br /></font><font color="#000080" face="Courier New">      {</font><font color="#000080"><br /></font><font color="#000080" face="Courier New">        
//no master</font><font color="#000080"><br /></font><font color="#000080" face="Courier New">        
return null;</font><font color="#000080"><br /></font><font color="#000080" face="Courier New">      }</font><font color="#000080"><br /></font><font color="#000080" face="Courier New">      else</font><font color="#000080"><br /></font><font color="#000080" face="Courier New">      {</font><font color="#000080"><br /></font><font color="#000080" face="Courier New">        
return UltimateMaster(ThePage.Master);</font><font color="#000080"><br /></font><font color="#000080" face="Courier New">      }</font><font color="#000080"><br /></font><font color="#000080" face="Courier New">}</font><font color="#000080"><br /><br /><font face="Courier New">//this will call itself until it runs out of Master Pages</font><br /></font><font color="#000080" face="Courier New">protected MasterPage UltimateMaster(MasterPage
ThePage)</font><font color="#000080"><br /></font><font color="#000080" face="Courier New">{</font><font color="#000080"><br /></font><font color="#000080" face="Courier New">      MasterPage
TheMaster;</font><font color="#000080"><br /><br /></font><font color="#000080" face="Courier New">      if
(ThePage.Master == null)</font><font color="#000080"><br /></font><font color="#000080" face="Courier New">      {</font><font color="#000080"><br /></font><font color="#000080" face="Courier New">          
TheMaster = ThePage;</font><font color="#000080"><br /></font><font color="#000080" face="Courier New">      }</font><font color="#000080"><br /></font><font color="#000080" face="Courier New">      else</font><font color="#000080"><br /></font><font color="#000080" face="Courier New">      {</font><font color="#000080"><br /></font><font color="#000080" face="Courier New">          
TheMaster = UltimateMaster(ThePage.Master);</font><font color="#000080"><br /><br /></font><font color="#000080" face="Courier New">      }</font><font color="#000080"><br /></font><font color="#000080" face="Courier New">      return
TheMaster;</font><font color="#000080"><br /></font><font color="#000080" face="Courier New">}</font><br /></blockquote>I'd add these methods to a base web page class, so I can access them
from all my pages.  Then it is easy to access the ultimate master page at any
time...<br /><blockquote><font color="#000080" face="Courier New">MasterPage TheUltimateMaster
= UltimateMaster(this);</font><br /></blockquote>To access any custom properties or methods that have been exposed, the
master page needs to be cast to its strong type...<br /><blockquote><font color="#000080" face="Courier New">MyUltimateMasterPageType MyMaster
= (MyUltimateMasterPageType) TheUltimateMaster; </font><br /></blockquote>Then the ultimate master page is ready to be used...<br /><blockquote><font color="#000080" face="Courier New">MyMaster.AUsefulMethod("SomethingSomehting"); </font><br /></blockquote>I haven't had the occasion to use nested master pages, but I thought
I'd offer this as an early Christmas present to anyone who does.<br /><br />
Happy Holidays.  Merry Christmas!<br /><p></p><img width="0" height="0" src="http://www.vpsw.com/blogbaby/aggbug.ashx?id=b187e79b-18a4-4edc-a0e8-61932ac53ae3" /></body>
      <title>Where Oh Where Has My Little Blog Gone</title>
      <guid isPermaLink="false">http://www.vpsw.com/blogbaby/PermaLink,guid,b187e79b-18a4-4edc-a0e8-61932ac53ae3.aspx</guid>
      <link>http://www.vpsw.com/blogbaby/PermaLink,guid,b187e79b-18a4-4edc-a0e8-61932ac53ae3.aspx</link>
      <pubDate>Fri, 21 Dec 2007 02:15:38 GMT</pubDate>
      <description>I went on vacation at the end of July and returned in early August. Life restarted in fits and starts.&amp;nbsp; But somehow I neglected to get this blog started again. Now that five months have passed, I think it is time to begin again.&amp;nbsp; So without further ado...&lt;br&gt;
&lt;br&gt;
Had a question on a forum today about how to access the top master page if you are
using nested master pages.&amp;nbsp; Seemed like a good time to break out some recursion.&amp;nbsp; 
&lt;br&gt;
&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#000080" face="Courier New"&gt;protected MasterPage UltimateMaster(Page
ThePage)&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;{&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if
(ThePage.Master == null)&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
//no master&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
return null;&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
return UltimateMaster(ThePage.Master);&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;}&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;br&gt;
&lt;font face="Courier New"&gt;//this will call itself until it runs out of Master Pages&lt;/font&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;protected MasterPage UltimateMaster(MasterPage
ThePage)&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;{&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MasterPage
TheMaster;&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if
(ThePage.Master == null)&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
TheMaster = ThePage;&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
TheMaster = UltimateMaster(ThePage.Master);&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return
TheMaster;&lt;/font&gt;&lt;font color="#000080"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#000080" face="Courier New"&gt;}&lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt;I'd add these methods to a base web page class, so I can access them
from all my pages.&amp;nbsp; Then it is easy to access the ultimate master page at any
time...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#000080" face="Courier New"&gt;MasterPage TheUltimateMaster
= UltimateMaster(this);&lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt;To access any custom properties or methods that have been exposed, the
master page needs to be cast to its strong type...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#000080" face="Courier New"&gt;MyUltimateMasterPageType MyMaster
= (MyUltimateMasterPageType) TheUltimateMaster; &lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt;Then the ultimate master page is ready to be used...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#000080" face="Courier New"&gt;MyMaster.AUsefulMethod("SomethingSomehting"); &lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt;I haven't had the occasion to use nested master pages, but I thought
I'd offer this as an early Christmas present to anyone who does.&lt;br&gt;
&lt;br&gt;
Happy Holidays.&amp;nbsp; Merry Christmas!&lt;br&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.vpsw.com/blogbaby/aggbug.ashx?id=b187e79b-18a4-4edc-a0e8-61932ac53ae3" /&gt;</description>
      <comments>http://www.vpsw.com/blogbaby/CommentView,guid,b187e79b-18a4-4edc-a0e8-61932ac53ae3.aspx</comments>
      <category>.NET</category>
      <category>2.0</category>
    </item>
    <item>
      <trackback:ping>http://www.vpsw.com/blogbaby/Trackback.aspx?guid=a1478711-4218-4c4c-a102-ad0eb2246a40</trackback:ping>
      <pingback:server>http://www.vpsw.com/blogbaby/pingback.aspx</pingback:server>
      <pingback:target>http://www.vpsw.com/blogbaby/PermaLink,guid,a1478711-4218-4c4c-a102-ad0eb2246a40.aspx</pingback:target>
      <dc:creator>Dean</dc:creator>
      <wfw:comment>http://www.vpsw.com/blogbaby/CommentView,guid,a1478711-4218-4c4c-a102-ad0eb2246a40.aspx</wfw:comment>
      <wfw:commentRss>http://www.vpsw.com/blogbaby/SyndicationService.asmx/GetEntryCommentsRss?guid=a1478711-4218-4c4c-a102-ad0eb2246a40</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">I hate writing the same code twice. 
Not just because I am a horrible typist, but because writing the same code twice means
testing it twice, debugging it twice, maintaining it twice, etc.  I recently
ran into a situation where this looked unavoidable.  I needed to write (a little
more than) a wee bit of code that evaluated values against arbitrary conditions in
the same way.  The twist was that these conditions could have different types.  
<br /><br />
I didn't want to duplicate the code for each type. However, I also wanted it to be
strongly typed, so I didn't want to resort to using the object type for everything. 
Since all the types in question are numeric, I could have simply coerced everything
into a decimal or a double type and written the bulk of the code against that one
type.  But I didn't like this for three reasons: 
<br /><ol><li>
It would be imprecise: I wanted to compare integers to integers when I could<br /></li><li>
It would require adding a layer of conversion logic</li><li>
It just didn't feel right.  It wasn't elegant.</li></ol>
Not all code is elegant, but it seems to flow much more easily and get working more
quickly when it is.  So while I was counting up the types I'd need to support
and contemplating the heinous sin of cut and paste coding, it occurred to me that
.NET 2.0 should allow me to solve this very elegantly, using <a href="http://msdn2.microsoft.com/en-US/library/512aeb7t%28vs.80%29.aspx">Generics</a>.  
<br /><br />
I have already fallen in love with the generic collections and have kicked the ArrayList
to the curb, so it was time to figure out how to make a generic class of my own devising.<br /><br />
The &lt;T&gt; is the key...<br /><br /><blockquote><font color="#0000ff" face="Courier New">public class OneRuleToBindThem&lt;T&gt; </font><br /></blockquote><br />
This tells the complier that the class will be created for the specified type in &lt;&gt;.<br /><br />
So I whipped up my first generic class. The simplified version looked vaguely like
this....<br /><br /><blockquote><font color="#0000ff" face="Courier New">public class OneRuleToBindThem&lt;T&gt;<br />
{<br />
    private T mMinimumValue;<br />
    private T mMaximumValue;<br />
    private const string PASS = "Pass";<br />
    private const string FAIL = "Fail";<br /><br />
    public OneRuleToBindThem(T MinimumValue, T MaximumValue)<br />
    {<br />
        mMinimumValue = MinimumValue;<br />
        mMaximumValue = MaximumValue;<br />
    }<br /><br />
    public string Evaluate(T ObservedValue)<br />
    {<br />
        string Result = PASS;<br />
        if (ObservedValue &gt; mMaximumValue)<br />
            Result = FAIL;<br />
        if (ObservedValue &lt; mMinimumValue)<br />
            Result = FAIL;<br /><br />
        return Result;<br />
    }<br />
}</font><br /></blockquote><br /><br />
That was too easy!  Let's compile it and move on...<br /><br /><blockquote><b><font color="#ff0000">Operator '&gt;' cannot be applied to operands
of type 'T' and 'T'   </font></b><br /></blockquote><br />
What in the la-di-da does that mean? Shazbot.  Why can't I compare a T with a
T?  They'll be the same type for pete's sake.  A little googling and reading
and OK, the compiler doesn't know if a supplied type will support the given operand,
so it properly throws an error.  Surely there must be a way around this, some
way to reassure the compiler that only appropriate types will be used, really!<br /><br />
A hint from <a href="http://community.strongcoders.com/blogs/ryan/default.aspx">Ryan
Olshan</a> led me to check out IComparable. Ah, it is possible to <a href="http://msdn2.microsoft.com/en-US/library/d5x73970%28VS.80%29.aspx">constrain</a> the
types that can instantiate the class.  So I tried...<br /><br /><blockquote><font color="#0000ff" face="Courier New">public class OneRuleToBindThem&lt;T&gt;
where T:IComparable</font><br /><font color="#0000ff" face="Courier New">{<br /></font><blockquote><font color="#0000ff" face="Courier New">//code you've seen before...</font><br /></blockquote><font color="#0000ff" face="Courier New">}<br /></font></blockquote><br />
Compile and...the same errors appear in the build.  Fudgesticks.<br /><br />
An idea flickered.  Since I would only be using types that implement IComparable,
maybe I could use the interface's <a href="http://msdn2.microsoft.com/en-us/library/system.icomparable.compareto.aspx">CompareTo</a> method
somehow.<br /><br />
So, I rewrote the Evaluate method...<br /><br /><blockquote><p><font color="#0000ff"><font face="Courier New">public string Evaluate(T ObservedValue)</font></font><font color="#0000ff" face="Courier New"><br />
{</font></p></blockquote><font color="#0000ff"><font face="Courier New">      
string Result = PASS;<br />
        if (ObservedValue.CompareTo(mMaximumValue)
&gt; 0)<br />
            Result = FAIL;<br />
        if (ObservedValue.CompareTo(mMinimumValue)
&lt; 0)<br />
            Result = FAIL;<br /><br />
        return Result;<br />
    }<br /></font></font><br />
F5 to compile and -- hoorah.  The darn thing works, well compiles anyway. 
Let's see if it actually works with a little test code...<br /><br /><font color="#0000ff"><font face="Courier New">       
OneRuleToBindThem&lt;int&gt; AnIntegerRule = new OneRuleToBindThem&lt;int&gt;(4, 10);<br />
        for (int Index = 1; Index &lt;= 11; Index++)<br />
        {<br />
            Debug.WriteLine(String.Format("{0}
: {1}", Index, AnIntegerRule.Evaluate(Index)));<br />
        }<br /><br />
        OneRuleToBindThem&lt;decimal&gt; ADecimalRule
= new OneRuleToBindThem&lt;decimal&gt;(4, 10);<br />
        for (decimal Index = 1M; Index &lt;= 11M;
Index+= 0.2M)<br />
        {<br />
            Debug.WriteLine(String.Format("{0}
: {1}", Index, ADecimalRule.Evaluate(Index)));<br />
        }</font></font><br /><br />
Good golly.  Worked on the first, ahem, try.  Now is the time on "OOP -
There it Is" when we dance.<br /><br />
Granted the example Evaluate method is only a few lines of code (and could be slimmer).
In this example it wouldn't be too onerous to store the MinimumValue and MaximumValue
as doubles, and then write an overloaded Evaluate method for each type using the appropriate
convert functions.  But when Evaluate is 20+ lines of code and the class needs
to support 3+ types, that's a shameful amount of cut-and-paste code. Shameful. 
<br /><br />
But with the Generic implementation, everything is strongly typed. And best of all,
there's only one method to test, debug and maintain! Once again, my fear of typing
led to a sweet little implementation.<br /><p></p><img width="0" height="0" src="http://www.vpsw.com/blogbaby/aggbug.ashx?id=a1478711-4218-4c4c-a102-ad0eb2246a40" /></body>
      <title>Operands, I Don't Need No Stinkin' Operands</title>
      <guid isPermaLink="false">http://www.vpsw.com/blogbaby/PermaLink,guid,a1478711-4218-4c4c-a102-ad0eb2246a40.aspx</guid>
      <link>http://www.vpsw.com/blogbaby/PermaLink,guid,a1478711-4218-4c4c-a102-ad0eb2246a40.aspx</link>
      <pubDate>Wed, 06 Jun 2007 03:46:14 GMT</pubDate>
      <description>I hate writing the same code twice.&amp;nbsp; Not just because I am a horrible typist, but because writing the same code twice means testing it twice, debugging it twice, maintaining it twice, etc.&amp;nbsp; I recently ran into a situation where this looked unavoidable.&amp;nbsp; I needed to write (a little more than) a wee bit of code that evaluated values against arbitrary conditions in the same way.&amp;nbsp; The twist was that these conditions could have different types.&amp;nbsp; &lt;br&gt;
&lt;br&gt;
I didn't want to duplicate the code for each type. However, I also wanted it to be
strongly typed, so I didn't want to resort to using the object type for everything.&amp;nbsp;
Since all the types in question are numeric, I could have simply coerced everything
into a decimal or a double type and written the bulk of the code against that one
type.&amp;nbsp; But I didn't like this for three reasons: 
&lt;br&gt;
&lt;ol&gt;
&lt;li&gt;
It would be imprecise: I wanted to compare integers to integers when I could&lt;br&gt;
&lt;/li&gt;
&lt;li&gt;
It would require adding a layer of conversion logic&lt;/li&gt;
&lt;li&gt;
It just didn't feel right.&amp;nbsp; It wasn't elegant.&lt;/li&gt;
&lt;/ol&gt;
Not all code is elegant, but it seems to flow much more easily and get working more
quickly when it is.&amp;nbsp; So while I was counting up the types I'd need to support
and contemplating the heinous sin of cut and paste coding, it occurred to me that
.NET 2.0 should allow me to solve this very elegantly, using &lt;a href="http://msdn2.microsoft.com/en-US/library/512aeb7t%28vs.80%29.aspx"&gt;Generics&lt;/a&gt;.&amp;nbsp; 
&lt;br&gt;
&lt;br&gt;
I have already fallen in love with the generic collections and have kicked the ArrayList
to the curb, so it was time to figure out how to make a generic class of my own devising.&lt;br&gt;
&lt;br&gt;
The &amp;lt;T&amp;gt; is the key...&lt;br&gt;
&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff" face="Courier New"&gt;public class OneRuleToBindThem&amp;lt;T&amp;gt; &lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt;
&lt;br&gt;
This tells the complier that the class will be created for the specified type in &amp;lt;&amp;gt;.&lt;br&gt;
&lt;br&gt;
So I whipped up my first generic class. The simplified version looked vaguely like
this....&lt;br&gt;
&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff" face="Courier New"&gt;public class OneRuleToBindThem&amp;lt;T&amp;gt;&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; private T mMinimumValue;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; private T mMaximumValue;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; private const string PASS = "Pass";&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; private const string FAIL = "Fail";&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public OneRuleToBindThem(T MinimumValue, T MaximumValue)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mMinimumValue = MinimumValue;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mMaximumValue = MaximumValue;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public string Evaluate(T ObservedValue)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string Result = PASS;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ObservedValue &amp;gt; mMaximumValue)&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; Result = FAIL;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ObservedValue &amp;lt; mMinimumValue)&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; Result = FAIL;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return Result;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
}&lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt;
&lt;br&gt;
&lt;br&gt;
That was too easy!&amp;nbsp; Let's compile it and move on...&lt;br&gt;
&lt;br&gt;
&lt;blockquote&gt;&lt;b&gt;&lt;font color="#ff0000"&gt;Operator '&amp;gt;' cannot be applied to operands
of type 'T' and 'T'&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/b&gt;
&lt;br&gt;
&lt;/blockquote&gt;
&lt;br&gt;
What in the la-di-da does that mean? Shazbot.&amp;nbsp; Why can't I compare a T with a
T?&amp;nbsp; They'll be the same type for pete's sake.&amp;nbsp; A little googling and reading
and OK, the compiler doesn't know if a supplied type will support the given operand,
so it properly throws an error.&amp;nbsp; Surely there must be a way around this, some
way to reassure the compiler that only appropriate types will be used, really!&lt;br&gt;
&lt;br&gt;
A hint from &lt;a href="http://community.strongcoders.com/blogs/ryan/default.aspx"&gt;Ryan
Olshan&lt;/a&gt; led me to check out IComparable. Ah, it is possible to &lt;a href="http://msdn2.microsoft.com/en-US/library/d5x73970%28VS.80%29.aspx"&gt;constrain&lt;/a&gt; the
types that can instantiate the class.&amp;nbsp; So I tried...&lt;br&gt;
&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff" face="Courier New"&gt;public class OneRuleToBindThem&amp;lt;T&amp;gt;
where T:IComparable&lt;/font&gt;
&lt;br&gt;
&lt;font color="#0000ff" face="Courier New"&gt;{&lt;br&gt;
&lt;/font&gt;&lt;blockquote&gt;&lt;font color="#0000ff" face="Courier New"&gt;//code you've seen before...&lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt;&lt;font color="#0000ff" face="Courier New"&gt;}&lt;br&gt;
&lt;/font&gt;&lt;/blockquote&gt;
&lt;br&gt;
Compile and...the same errors appear in the build.&amp;nbsp; Fudgesticks.&lt;br&gt;
&lt;br&gt;
An idea flickered.&amp;nbsp; Since I would only be using types that implement IComparable,
maybe I could use the interface's &lt;a href="http://msdn2.microsoft.com/en-us/library/system.icomparable.compareto.aspx"&gt;CompareTo&lt;/a&gt; method
somehow.&lt;br&gt;
&lt;br&gt;
So, I rewrote the Evaluate method...&lt;br&gt;
&lt;br&gt;
&lt;blockquote&gt;
&lt;p&gt;
&lt;font color="#0000ff"&gt;&lt;font face="Courier New"&gt;public string Evaluate(T ObservedValue)&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff" face="Courier New"&gt;
&lt;br&gt;
{&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt;&lt;font color="#0000ff"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
string Result = PASS;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ObservedValue.CompareTo(mMaximumValue)
&amp;gt; 0)&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; Result = FAIL;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ObservedValue.CompareTo(mMinimumValue)
&amp;lt; 0)&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; Result = FAIL;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return Result;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;br&gt;
F5 to compile and -- hoorah.&amp;nbsp; The darn thing works, well compiles anyway.&amp;nbsp;
Let's see if it actually works with a little test code...&lt;br&gt;
&lt;br&gt;
&lt;font color="#0000ff"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
OneRuleToBindThem&amp;lt;int&amp;gt; AnIntegerRule = new OneRuleToBindThem&amp;lt;int&amp;gt;(4, 10);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int Index = 1; Index &amp;lt;= 11; Index++)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&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; Debug.WriteLine(String.Format("{0}
: {1}", Index, AnIntegerRule.Evaluate(Index)));&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; OneRuleToBindThem&amp;lt;decimal&amp;gt; ADecimalRule
= new OneRuleToBindThem&amp;lt;decimal&amp;gt;(4, 10);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (decimal Index = 1M; Index &amp;lt;= 11M;
Index+= 0.2M)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&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; Debug.WriteLine(String.Format("{0}
: {1}", Index, ADecimalRule.Evaluate(Index)));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/font&gt;
&lt;br&gt;
&lt;br&gt;
Good golly.&amp;nbsp; Worked on the first, ahem, try.&amp;nbsp; Now is the time on "OOP -
There it Is" when we dance.&lt;br&gt;
&lt;br&gt;
Granted the example Evaluate method is only a few lines of code (and could be slimmer).
In this example it wouldn't be too onerous to store the MinimumValue and MaximumValue
as doubles, and then write an overloaded Evaluate method for each type using the appropriate
convert functions.&amp;nbsp; But when Evaluate is 20+ lines of code and the class needs
to support 3+ types, that's a shameful amount of cut-and-paste code. Shameful. 
&lt;br&gt;
&lt;br&gt;
But with the Generic implementation, everything is strongly typed. And best of all,
there's only one method to test, debug and maintain! Once again, my fear of typing
led to a sweet little implementation.&lt;br&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.vpsw.com/blogbaby/aggbug.ashx?id=a1478711-4218-4c4c-a102-ad0eb2246a40" /&gt;</description>
      <comments>http://www.vpsw.com/blogbaby/CommentView,guid,a1478711-4218-4c4c-a102-ad0eb2246a40.aspx</comments>
      <category>2.0</category>
      <category>Generics</category>
    </item>
    <item>
      <trackback:ping>http://www.vpsw.com/blogbaby/Trackback.aspx?guid=c163aa6c-bbc2-4175-a653-00e46e2de3a1</trackback:ping>
      <pingback:server>http://www.vpsw.com/blogbaby/pingback.aspx</pingback:server>
      <pingback:target>http://www.vpsw.com/blogbaby/PermaLink,guid,c163aa6c-bbc2-4175-a653-00e46e2de3a1.aspx</pingback:target>
      <dc:creator>Dean</dc:creator>
      <wfw:comment>http://www.vpsw.com/blogbaby/CommentView,guid,c163aa6c-bbc2-4175-a653-00e46e2de3a1.aspx</wfw:comment>
      <wfw:commentRss>http://www.vpsw.com/blogbaby/SyndicationService.asmx/GetEntryCommentsRss?guid=c163aa6c-bbc2-4175-a653-00e46e2de3a1</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
There are four (development) life annoyances that I can do without:
</p>
        <ol>
          <li>
Recruiters who only use the state abbreviation to describe a job location. "Urgent
need for Senior .NET Developer, Location: CA"</li>
          <li>
Forum posters who demand code for entire applications. "Please send me chat server
code -- urgent."</li>
          <li>
Repeated requests for Interview Questions.  <a href="http://community.strongcoders.com/blogs/vpsw/archive/2006/10/23/the-only-interview-question-you-ll-ever-need-to-answer-click-here.aspx">I've
covered this elsewhere.</a><br /></li>
          <li>
Lazy gits who can't be bothered to learn how to read either C# or VB.NET. "Thanks
for the answer, but my project is in VB.NET, I don't understand C#."</li>
        </ol>
At least once a week, I'll answer a question on forum somewhere with a code example
and get a "Thank you, but" response.  Often accompanied by a request to rewrite
the code in their language of choice.  With perfectly named variables and smilies
in the comments.<br /><br />
This burns my toast.  It takes enormous willpower not to simply respond "find
another job you lazy git". 
<br /><br />
A) We're never talking more than 50 lines of code, usually it is around 20.  
<br />
B) 3/4 of the friggin' code is manipulating <b>.NET Framework objects</b> using <b>.NET
Framework methods</b> and <b>.NET Framework properties</b> -- which are -- wait for
it...<u><font color="#ff0000" size="4"><br /><br />
THE SAME FOR BOTH C# and VB.NET!</font></u><br /><br />
So this post is a (no longer) quick and dirty guide for figuring out how to translate
C# into VB.NET (and vice versa, but frankly 92.6% of the time its a VB coder who complains). 
It will become my standard response for all the future lazy gits.<br /><br />
Let's start at the top (of the class file that is)...<br /><br />
Need to reference a namespace...<br /><blockquote><font color="#0000ff">ala C#: using System.Data.SqlClient;</font><br /><font color="#008000">ala VB: Imports System.Data.SqlClient<br /></font><br /></blockquote>Note the ubiquitous semicolon (<b>;</b>).  C# statements can span
pages like a sentence in <a href="http://www.online-literature.com/james_joyce/ulysses/">Ulysses</a>. 
They don't end until the ; appears. VB statements get one line to do their business,
unless they are ended with the awkward _ line continuation (underscore) which allows
them to continue one more line unless they are ended with the awkward _, repeat.<br /><br />
A class...<br /><blockquote><font color="#0000ff">ala C#: public class TheClassINeverHad<br />
           {<br />
             //fields, methods and properties
-- oh my!<br />
            }<br /></font><font color="#008000">ala VB: Public Class TheClassINeverHad<br />
             'fields, methods and properties
-- oh my!<br />
          End Class<br /></font></blockquote> Ooooh no, C# does everything in lower case! (and its compiler
is very strict about keeping it that way)<br />
VB Capitalizes! (not that its compiler cares)<br /><br />
In C#, all code blocks are marked with with brackets{}. 
<br />
In VB, code blocks usually go until a line that starts with End followed by the type
of code block, which iin this case is Class.<br /><br />
Fancier class declarations...<br /><blockquote><font color="#0000ff">ala C#: public abstract class TheClassINeverHad</font><br /><font color="#008000">ala VB: Public MustInherit Class TheClassINeverHad</font><br /></blockquote><blockquote><font color="#0000ff">ala C#: public sealed class TheClassINeverHad</font><br /><font color="#008000">ala VB: Public NotInheritable Class TheClassINeverHad</font><br /></blockquote>Why VB.NET couldn't use the more common OOP vernacular is beyond me.<br /><br />
Interface declarations...<br /><blockquote><font color="#0000ff">ala C#: public interface IPractical</font><br /><font color="#008000">ala VB: Public Interface IPractical</font><br /></blockquote>Hooray, that should be clear even to the laziest git.<br /><br />
Extending a class...<br /><blockquote><font color="#0000ff">ala C#: public class TheClassINeverHad: APracticalClass</font><br /><font color="#008000">ala VB: Public Class TheClassINeverHad<br />
             Inherits APracticalClass<br /></font></blockquote>The humble colon does a lot here in C#.  The VB syntax leaves
nothing to doubt.<br /><br />
Implementing an interface...<br /><blockquote><font color="#0000ff">ala C#: public class TheClassINeverHad: IPractical</font><br /><font color="#008000">ala VB: Public Class TheClassINeverHad<br />
             Implements IPractical<br /></font></blockquote>or interfaces...<br /><blockquote><font color="#0000ff">ala C#: public class TheClassINeverHad: IPractical,
IRidiculous</font><br /><font color="#008000">ala VB: Public Class TheClassINeverHad<br />
             Implements IPractical<br />
             Implements IRidiculous<br /></font></blockquote>The colon does everything!  
<br /><br />
Extending and implementing...<br /><blockquote><font color="#0000ff">ala C#: public class TheClassINeverHad: APracticalClass,
IPractical, IRidiculous</font><br /><font color="#008000">ala VB: Public Class TheClassINeverHad<br />
             Inherits APracticalClass<br /></font><font color="#008000">             
Implements IPractical</font><br /><font color="#008000">              Implements
IRidiculous</font><br /></blockquote> A comment...<br /><blockquote><font color="#0000ff">ala C#: //This is a 1 line comment<br />
          /* This starts a multiline comment<br />
          This ends a multiline comment */<br /></font><font color="#008000">ala VB: 'This is a one line comment<br /></font></blockquote>There is no such thing as a multline comment in VB, but who comments
code anyway?<br /><br />
You really should though.<br /><br />
a field...<br /><blockquote><font color="#0000ff">ala C#: private int SomeNumberIWillUse;</font><br /><font color="#008000">ala VB: Private SomeNumberIWillUse as Integer</font><br /></blockquote> VB.NET surrounds the name of the variable with its access modifier and
type.  C# gets all that out of the way then tells you the name.<br /><br />
a constant...<br /><blockquote><font color="#0000ff">ala C#: private const string LAZY_GIT = "Lazy Git";</font><br /><font color="#008000">ala VB: Private Const LAZY_GIT as String = "Lazy Git"</font><br /></blockquote>a constructor...<br /><blockquote><font color="#0000ff">ala C#: public TheClassINeverHad()<br />
            {<br />
                //Do Something
Useful<br />
             }<br /></font><font color="#008000">ala VB: public Sub New()<br />
             'Do Something Useful<br />
          End Sub<br /></font></blockquote><font color="#008000"><br /></font>C# uses the name of the class to indicate the constructor. The Sub New in VB
is a little clearer at first blush.<br /><br />
A structure can be a handy little doo-dad when a class is overkill...<br /><blockquote><font color="#0000ff">ala C#: public struct Soda<br />
           {<br />
                 public
string Name;<br />
                 public int
Calories;<br />
            }<br /></font><font color="#008000">ala VB: Public Structure Soda<br />
             Public Name as String<br />
             Public Calories as Integer<br />
          End Structure<br /></font></blockquote> More brackets in C#, another End statement in VB. C# shows it
inclination for abbreviation. Patterns develop.<br /><br />
Let's not forget enumerations...<br /><blockquote><font color="#0000ff">ala C#: public enum PlanetValues<br />
           {<br />
                   
Mercury = 0,<br />
                   
Venus = 1,<br />
                   
Earth = 2,<br />
                   
Mars = 3,<br />
                   
Jupiter = 4,<br />
                   
Saturn = 5,<br />
                   
Uranus = 6,<br />
                   
Neptune = 7,<br />
                   
Pluto = 8<br />
            }<br /></font><font color="#0000ff">           
public enum PlanetValues<br />
           {<br />
                   
Mercury,<br />
                   
Venus,<br />
                   
Earth,<br />
                   
Mars,<br />
                   
Jupiter,<br />
                   
Saturn,<br />
                   
Uranus,<br />
                   
Neptune,<br />
                   
Pluto<br />
            }</font><br /><font color="#008000">ala VB: Public Enum PlanetValues<br />
             Mercury = 0<br />
             Venus = 1<br />
             Earth = 2<br />
             Mars = 3<br />
             Jupiter = 4<br />
             Saturn = 5<br />
             Uranus = 6<br />
             Neptune = 7<br />
             Pluto = 8<br />
          End Enum<br /><br /></font><font color="#008000">        Public Enum PlanetValues<br />
             Mercury 
<br />
             Venus 
<br />
             Earth 
<br />
             Mars 
<br />
             Jupiter 
<br />
             Saturn 
<br />
             Uranus 
<br />
             Neptune 
<br />
             Pluto 
<br />
          End Enum</font><br /></blockquote>All these enumerations are identical.  If no value for the first
element is specified it is set = 0, every other unspecified element is incremented
one from the previous element. Curiously the C# syntax uses commas and not semi-colons.<br /><br />
a local variable...<br /><blockquote><font color="#0000ff">ala C#: string DeveloperPersona;</font><br /><font color="#008000">ala VB: Dim DeveloperPersona as String</font><font color="#008000"><br /></font></blockquote>arrays...<br /><blockquote><font color="#0000ff">ala C#: string[] CoolDevTools;<br />
           string[] CoolDevTools = new string[5];<br />
           //assignment<br />
          CoolDevTools[0] = SomeString;<br /></font><font color="#008000">ala VB: Dim CoolDevTools as String()<br />
          Dim CoolDevTools(5) as String<br />
          'assignment<br />
          CoolDevTools(0) = SomeString<br />
              </font><br /></blockquote>C# uses square brackets [] for the elements.<br />
VB uses parentheses ().<br /><br />
Ditto for collection elements...<br /><blockquote><font color="#0000ff">ala C#: AnObjectType SomeObject = (</font><font color="#0000ff">AnObjectType)</font><font color="#0000ff">SomeHashtable[SomeKey];<br />
           A</font><font color="#0000ff">nObjectType
SomeObject = (</font><font color="#0000ff">AnObjectType)</font><font color="#0000ff">SomeArrayList[SomeIndex];</font><font color="#0000ff"><br /></font><font color="#008000">ala VB:  Dim SomeObject as AnObjectType = SomeHashtable(SomeKey)<br />
           </font><font color="#008000">Dim
SomeObject as AnObjectType = SomeArrayList(SomeIndex)</font><br /><font color="#008000">           'or if Option
Strict is on<br />
          D</font><font color="#008000">im SomeObject
as AnObjectType = CType(SomeHashtable(SomeKey), AnObjectType)<br />
          </font><font color="#008000">Dim SomeObject
as AnObjectType = </font><font color="#008000">CType(</font><font color="#008000">SomeArrayList(SomeIndex)</font><font color="#008000">,
AnObjectType)</font><br /><font color="#008000">               </font></blockquote>C#
doesn't do narrowing implicit type casts,  so an element retrieved from an untyped
collection must be explicitly cast.  This is done by wrapping the object type
in parentheses and smooshing it against the collection name.<br />
VB will implicitly cast unless <a href="http://msdn2.microsoft.com/en-us/library/zcd4xwzs%28vs.71%29.aspx">Option
Strict </a>is On, in which case the CType method must be used to cast the element
returned to the proper type.<br /><br />
a method that does NOT return a value...<br /><blockquote><font color="#0000ff">ala C#: public void ThePerfectMethod(string DeveloperName)<br />
             {<br />
                // coding goodness<br />
             }<br /></font><font color="#008000">ala VB: Public Sub ThePerfectMethod(DeveloperName as
String)<br />
                'Coding Goodness<br />
          End Sub<br /></font></blockquote>a method that does return a value...<br /><blockquote><font color="#0000ff">ala C#: public int ThePerfectMethod(string DeveloperName)<br />
             {<br />
                // coding goodness<br />
               
return 42;<br />
             }<br /></font><font color="#008000">ala VB: Public Function ThePerfectMethod(DeveloperName
as String) as Integer<br />
                'Coding Goodness<br />
                Return 42<br />
          End Function<br /></font></blockquote> As with fields and constants, C# states the access modifier and
the type being returned by the method before getting to the name.  When nothing
is returned the type is <b>void</b>.<br />
VB has separate keywords to differentiate between methods that return nada (Sub) and
those that return something (Function).<br />
Parameters are types just like variables are in each language:  type Name in
C#, Name as Type in VB.<br /><br />
a read/write property...<br /><blockquote><font color="#0000ff">ala C#: public int TheAnswer<br />
             {<br />
               get{  
return mTheAnswer;}<br />
               set{  mTheAnswer
= value;}<br />
             }<br /></font><font color="#008000">ala VB: Public Property TheAnswer() as Integer<br />
                Get<br />
                   
Return mTheAnswer<br />
                End Get<br />
                Set (Value
as Integer)<br />
                  
mTheAnswer = Value<br />
                End Set<br />
                  
   
<br />
          End Property</font><br /></blockquote>a read-only property...<br /><blockquote><blockquote><font color="#0000ff">ala C#: public int TheAnswer<br />
             {<br />
               get{  
return mTheAnswer;}<br />
             }<br /></font><font color="#008000">ala VB: Public ReadOnly Property TheAnswer() as Integer<br />
                Get<br />
                   
Return mTheAnswer<br />
                End Get<br />
          End Property<br /></font></blockquote></blockquote>a write-only property...<br /><blockquote><font color="#0000ff">ala C#: public int TheAnswer<br />
             {<br />
               set{  mTheAnswer
= value;}<br />
             }<br /></font><font color="#008000">ala VB: Public WriteOnly Property TheAnswer() as Integer<br />
                Set (Value
as Integer)<br />
                  
mTheAnswer = Value<br />
                End Set<br />
                  
   
<br />
          End Property</font></blockquote>VB.NET
needs to be explicity told a property is read- or write-only, C# is happy as long
as there is a get or set -- it figures it out.<br /><br />
static(Shared) members...<br /><blockquote><font color="#0000ff">ala C#: private static int mANumberEveryoneNeeds;<br />
           public static ANumberEveryoneNeeds<br />
           {<br />
                get{return </font><font color="#0000ff">mANumberEveryoneNeeds;}</font><br /><font color="#0000ff">           }<br />
           public static void ResetTheNumber()<br />
           {<br />
                </font><font color="#0000ff">mANumberEveryoneNeeds
= 0;</font><br /><font color="#0000ff">           }<br /></font><font color="#008000">ala VB: Private Shared mANumberEveryonNeeds as Integer<br />
           Public Readonly Shared Property
ANumberEveryoneNeeds() as Integer<br />
                Get<br />
                  
Return mANumberEveryoneNeeds<br />
                End Get<br />
           End Property<br />
           Public Shared Sub ResetTheNumber
()<br />
                
mANumberEveryoneNeeds = 0<br />
           End Sub<br /></font></blockquote><br />
Shared = static.  static = Shared. Static members are shared by ALL instances
of a class.  The meaning of static is not as immediately a clear as Shared. But
it's not that hard to remember.<br /><br />
Branching...<br /><blockquote><font color="#0000ff">ala C#: if(SomeVariable == 42)<br />
             {<br />
                Answer = "That's
it!";<br />
                HasWisdom = true;<br />
             }<br />
           else<br />
             {<br />
                Answer = "That's
not it.";<br />
               
HasWisdon = false;<br />
             }<br /><br />
          //one line syntax<br /></font><font color="#0000ff">           if(SomeVariable
== 42)<br />
                Answer = "That's
it!";<br />
           else<br />
                Answer = "That's
not it.";<br />
                </font><br /><font color="#0000ff"></font><font color="#0000ff"><br /></font><font color="#008000">ala VB: If SomeVariable = 42 Then<br />
             Answer = "That's it!"<br />
             HasWisdom
= True<br />
          Else<br />
             Answer = "That's not it."<br />
             HasWisdom
= False<br />
          End if<br /></font></blockquote>There's no Then in C#, the boolean expression is wrapped in parentheses
and the code to execute is within {}. The brackets are not required if the condition
only executes one line.  Like most other constructs in VB, the code block ends
with a uniquely named End statement: End If. 
<br /><br />
Note in C# the == is an evaluation operator, as opposed to the assignment operator
=.  In VB = performs both tasks. 
<br /><br />
What fun is an If statement without boolean logic...<br /><blockquote><font color="#0000ff">ala C#: if(!Page.IsPostBack) //Not operator<br />
           </font><font color="#0000ff">if(Night
!= Day) //Inequality<br />
           </font><font color="#0000ff">if(Night
== Day &amp; Pigs.CurrentState == PigState.Flying) // And</font><br /><font color="#0000ff">           if(</font><font color="#0000ff">Night
== Day &amp;&amp; Pigs.CurrentState == PigState.Flying</font><font color="#0000ff">)
//Conditional And<br />
           </font><font color="#0000ff">if(Night
== Day | Pigs.CurrentState == PigState.Flying) // Or<br />
           </font><font color="#0000ff">if(Night
== Day || Pigs.CurrentState == PigState.Flying) // Conditional Or<br />
           </font><font color="#0000ff">if(Night
== Day ^ Pigs.CurrentState == PigState.Flying) // Xor</font><br /><br /><font color="#0000ff"><br /></font><font color="#008000">ala VB: If Not Page.IsPostBack Then<br />
           If Night &lt;&gt; Day Then 'Inequality<br />
           If Night = Day And Pigs.CurrentState
= PigState.Flying Then 
<br />
           </font><font color="#008000">If
Night = Day AndAlso Pigs.CurrentState = PigState.Flying Then 'Conditional And</font><br /><font color="#008000">           If Night
= Day Or Pigs.CurrentState = PigState.Flying Then 
<br />
           </font><font color="#008000">If
Night = Day OrElse Pigs.CurrentState = PigState.Flying Then 'Conditional Or<br />
           </font><font color="#008000">If
Night = Day Xor Pigs.CurrentState = PigState.Flying Then</font><br /><font color="#008000">            
<br /></font></blockquote>VB spells everything out, though &lt;&gt; is a unique feature
of the language.  The conditional operators AndAlso (&amp;&amp;) and OrElse(||)
are tres useful, they short circuit the code and stop evaluting as soon as the appropriate
condition is met. 
<br /><br />
And when If Then is isn't enough...<br /><blockquote><font color="#0000ff">ala C#: </font><font color="#0000ff">switch(SelectedPlanet)</font><br /><font color="#0000ff">            {<br />
                 case
PlanetValues.Earth:<br />
                     
message = "Live there";<br />
                     
break;<br />
                 case
PlanetValues.Venus:<br />
                 case
PlanetValues.Mars:<br />
                  
   message = "Landed there";<br />
                  
   break;<br />
                 </font><font color="#0000ff">case
PlanetValues.Mercury:<br />
                 case
PlanetValues.Jupiter:<br />
                 case
PlanetValues.Saturn:<br />
                 case
PlanetValues.Uranus:<br />
                 case
PlanetValues.Neptune:<br />
                  
   message = "Flew by";<br />
                  
   break;<br />
                  case
PlanetValues.Pluto:<br />
                  
   message = "Is it a planet?"<br />
                  
   break;<br />
                  
default:<br />
                  
   message = "Never heard of it";<br />
                  
   break;<br />
           }</font><font color="#0000ff"><br />
            </font><font color="#0000ff"><br /></font><font color="#008000">ala VB: Select Case SelectedPlanet<br />
                Case PlanetValues.Earth<br />
                  
message = "Live there"<br />
                Case PlanetValues.Venus,
PlanetValues.Mars<br />
                  
message = "Landed there"<br />
                Case PlanetValues.Mercury,
PlanetValues.Jupiter, PlanetValues.Saturn, PlanetValues.Uranus, PlanetValues.Neptune<br />
                  
message = "Flew by"<br />
                Case PlanetValues.Pluto<br />
                  
message = "Is it a planet?"<br />
                Case Else<br />
                  
message = "Never heard of it"<br />
          End Select</font><font color="#008000"></font><br /></blockquote>In C#, there's only one value per case, but once a supplied value matches
a case, the code will "fall through" until it finds a case that executes code. 
All cases that have code must end with a break;. 
<br />
In VB, multiple values can be present on a line, it's also possible to do <a href="http://msdn2.microsoft.com/en-us/library/cy37t14y%28VS.71%29.aspx">ranges.</a> The
code cannot fall through in VB, but the extra flexibility for defining case values
makes it unecessary. 
<br /><br />
For Loops...<br /><blockquote><font color="#0000ff">ala C#: for(int Index = 0; Index &lt; SomeIntegerArray.Length;
Index ++)<br />
             {<br />
                 Total
+= SomeIntegerArray[Index];<br />
                 CallSomeOtherFunction(SomeIntegerArray[Index]);<br />
             }<br />
             //A single line For Loop
can be done without the brackets<br />
            </font><font color="#0000ff">for(int
Index = 0; Index &lt; SomeIntegerArray.Length; Index ++)<br />
                </font><font color="#0000ff">Total
+= SomeIntegerArray[Index];<br /></font><font color="#0000ff"><br /></font><font color="#008000">ala VB: For Index as Integer = 0 to SomeIntegerArray.Length
-1<br />
                Total += SomeIntegerArray(Index)<br />
                CallSomeOtherFunction(SomeIntegerArray(Index))<br />
          Next</font></blockquote><br />
In C#, {} brackets define what code gets looped, but a single line statement does
not require brackets. Iteration step size is always specified<br />
VB always requires the Next statement.  The iteration step size defaults to 1
for VB, to change the iteration step size...<br /><br /><blockquote><font color="#0000ff">ala C#: for(int Index = 0; Index &lt; SomeIntegerArray.Length;
Index += 2)<br />
             {<br />
                 Total
+= SomeIntegerArray[Index];<br />
                 CallSomeOtherFunction(SomeIntegerArray[Index]);<br />
             }<br />
            </font><font color="#0000ff"><br /></font><font color="#0000ff"><br /></font><font color="#008000">ala VB: For Index as Integer = 0 to SomeIntegerArray.Length
-1 Step 2<br />
                Total += SomeIntegerArray(Index)<br />
                </font><font color="#008000">CallSomeOtherFunction(SomeIntegerArray(Index))</font><br /><font color="#008000">           Next</font></blockquote>To
break out of the loop before it completes...<br /><blockquote><font color="#0000ff">ala C#: for(int Index = 0; Index &lt; SomeIntegerArray.Length;
Index += 2)<br />
             {<br />
                 Total
+= SomeIntegerArray[Index];<br />
                 if(CallSomeOtherFunction(SomeIntegerArray[Index])
== false)<br />
                  
break;<br />
             }</font><font color="#0000ff"><br /></font><font color="#0000ff"><br /></font><font color="#008000">ala VB: For Index as Integer = 0 to SomeIntegerArray.Length
-1 Step 2<br />
                Total += SomeIntegerArray(Index)<br />
                If </font><font color="#008000">CallSomeOtherFunction(SomeIntegerArray(Index))
= False Then<br />
                  
Exit For<br />
                End if<br /></font><font color="#008000">           Next</font></blockquote>break
is used to get out of every kind of loop in C#.  The command for exiting a loop
in VB.NET depends on the type of the loop. This can come in handy for nested loops
of different types.<br /><br />
For each loops...<br /><br /><blockquote><font color="#0000ff">ala C#: foreach(Universe PossibleUniverse in PossibleUniverses)<br />
             {<br />
                 if(PossibleUniverse.HasStrongForce)<br />
                 {<br />
                  
   
<br />
                  
   AddToViableCandidates(PossibleUniverse);<br />
                 }<br />
             }<br />
            </font><font color="#0000ff"><br /></font><font color="#0000ff"><br /></font><font color="#008000">ala VB: For Each PossibleUniverse as Universe in PossibleUniverses 
<br />
                If PossibleUniverse.HasStrongForce
Then<br />
                  
AddToViableCandidates(PossibleUniverse)<br />
                End if<br />
          Next<br /><br /></font></blockquote>Ignore the brackets and the for each loops look a lot alike.<br /><br /><br />
Do While Loops...<br /><blockquote><font color="#0000ff">ala C#: do<br />
             {<br />
                 Total
+= SomeIntegerArray[Index];<br />
                 if(CallSomeOtherFunction(SomeIntegerArray[Index])
== false)<br />
                  
break;<br />
                 Index++;<br />
             }<br />
             while(Index &lt; SomeIntegerArray.Length);<br /></font><font color="#0000ff"><br /></font><font color="#008000">ala VB: Do<br />
                Total += SomeIntegerArray(Index)<br />
                If </font><font color="#008000">CallSomeOtherFunction(SomeIntegerArray(Index))
= False Then<br />
                  
Exit Do<br />
                End if<br />
               
Index += 1<br /></font><font color="#008000">           Loop While
Index &lt; SomeIntegerArray.Length<br /><br /></font><font color="#008000">          Do </font><font color="#008000">While
Index &lt; SomeIntegerArray.Length</font><br /><font color="#008000">                
Total += SomeIntegerArray(Index)<br />
                If </font><font color="#008000">CallSomeOtherFunction(SomeIntegerArray(Index))
= False Then<br />
                  
Exit Do<br />
                End if<br />
                Index += 1<br /></font><font color="#008000">           Loop </font><br /></blockquote><br />
The do loop in C# always executes at least once.  The top version of the VB loop
does as well.  While the second version evaluates the condition before executing.
This is the one of the few code structures in VB that doesn't denote it's end using
an End statement (the others being the for and for each loops). If it did it would
look something like this...<br /><font color="#ff1493"><br />
          'This is not legal syntax -- just what
a Do loop would look like if VB were maddeningly consistent<br />
          Do<br />
                Total +=SomeIntegerArray(Index)<br />
          End Do While Index &lt; SomeIntegerArray.Length<br /></font><br />
Which is just goofy.<br /><br />
Do Until Loops...<br /><blockquote><font color="#0000ff">ala C#: do<br />
             {<br />
                 Total
+= SomeIntegerArray[Index];<br />
                 if(CallSomeOtherFunction(SomeIntegerArray[Index])
== false)<br />
                  
break;<br />
                 Index++;<br />
             }<br />
             while(Index &lt; SomeIntegerArray.Length);<br /></font><font color="#0000ff"><br /></font><font color="#008000">ala VB: Do<br />
                Total += SomeIntegerArray(Index)<br />
                If </font><font color="#008000">CallSomeOtherFunction(SomeIntegerArray(Index))
= False Then<br />
                  
Exit Do<br />
                End if<br />
                Index += 1<br /></font><font color="#008000">           Loop Until
Index = SomeIntegerArray.Length<br /><br /></font><font color="#008000">          Do </font><font color="#008000">Until
Index = SomeIntegerArray.Length</font><br /><font color="#008000">                
Total += SomeIntegerArray(Index)<br />
                If </font><font color="#008000">CallSomeOtherFunction(SomeIntegerArray(Index))
= False Then<br />
                  
Exit Do<br />
                End if<br />
                Index += 1<br /></font><font color="#008000">           Loop </font><br /></blockquote><br />
Wait a second -- there's no <b>do until</b> in C#. <b>Until</b> is just the other
side of <b>while</b>.  Instead of executing <b>while</b> a condition is true,
it executes <b>until</b> it is true. When moving from VB.NET to C# just use the while
and flip the condition to its opposite. Again the C# loop and the first VB loop execute
at least once.  
<br /><br />
And the last loop is the plain old while loop...<br /><blockquote><font color="#0000ff">ala C#: </font><font color="#0000ff">while(Index
&lt; SomeIntegerArray.Length)</font><br /><font color="#0000ff">              {<br />
                 Total
+= SomeIntegerArray[Index];<br />
                 if(CallSomeOtherFunction(SomeIntegerArray[Index])
== false)<br />
                  
break;<br />
                 Index++;<br />
             }<br />
            </font><font color="#0000ff"><br /></font><font color="#008000">ala VB: While </font><font color="#008000">Index &lt;
SomeIntegerArray.Length<br /></font><br /><font color="#008000">                
Total += SomeIntegerArray(Index)<br />
                If </font><font color="#008000">CallSomeOtherFunction(SomeIntegerArray(Index))
= False Then<br />
                  
Exit While<br />
                End if<br />
                Index += 1<br /></font><font color="#008000">           End 
While 
<br /></font><font color="#008000">         </font><font color="#008000"></font><br /></blockquote> While loops in both languages evaluate the condition before executing. 
Note the while uses the familiar Exit While to break and the End While to terminate
the loop.<br /><br />
Finally, a tricky difference -- hooking up event handlers...<br /><blockquote><font color="#0000ff">ala C#: </font><font color="#0000ff">SomeButton.Click
+= new ButtonEventHandler(SomeButton_Click);</font><font color="#0000ff"></font><br /><font color="#0000ff">             </font><br /><font color="#008000">ala VB: AddHandler SomeButton.Click, AddressOf SomeButton_Click</font><br /><br /><font color="#008000">          'or directly declare
it</font><br /><font color="#008000">           Sub SomeButton_Click(ByVal
sender As System.Object, ByVal e As System.EventArgs) Handles SomeButton.Click</font><br /></blockquote>VB lets you hook up the Handler on the event declaration or add the handler
dynamically.  C# only allows the dynamic hook.  
<br /><br />
I think this post has sufficiently covered 93.7% of commonly encountered code. 
I'd cover <a href="http://msdn2.microsoft.com/en-us/library/512aeb7t.aspx">Generics</a> (<a href="http://msdn2.microsoft.com/en-us/library/ms379608%28vs.80%29.aspx">VB
usage)</a>  but I think anyone working with Generics probably doesn't have any
problems reading either language.<br /><br />
Here are some reference links...<br /><ul><li><a href="http://msdn2.microsoft.com/en-us/library/6a71f45d.aspx">C# Operators</a></li><li><a href="http://msdn2.microsoft.com/en-us/library/x53a06bb.aspx">C# Keywords</a></li><li><a href="http://msdn2.microsoft.com/en-us/library/ksh7h19t%28VS.71%29.aspx">VB.NET
Keywords</a></li><li><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsintro7/html/vxgrfLanguageEquivalents.asp">Language
Equivalents</a></li></ul>
And for the truly lazy or people who have to translate more than 20 lines of code,
there are converters (though you might get some <a href="http://www.vpsw.com/blogbaby/PermaLink,guid,bb634e82-a78f-4fca-9d5d-a63616d70f99.aspx">interesting
results</a>) ...<br /><ul><li><a href="http://www.tangiblesoftwaresolutions.com/">Tanglible Software</a></li><li><a href="http://www.developerfusion.co.uk/utilities/convertcsharptovb.aspx">Developer
Fusion</a></li><li><a href="http://www.google.com/search?q=c%23+vb+converter&amp;sourceid=navclient-ff&amp;ie=UTF-8&amp;rlz=1B3GGGL_enUS176US213&amp;aq=t">Or
Google For More</a></li></ul>
So learn 'em both -- double your code examples, double your employment opportunities
-- double your fun.<br /><img width="0" height="0" src="http://www.vpsw.com/blogbaby/aggbug.ashx?id=c163aa6c-bbc2-4175-a653-00e46e2de3a1" /></body>
      <title>Airing of Grievances</title>
      <guid isPermaLink="false">http://www.vpsw.com/blogbaby/PermaLink,guid,c163aa6c-bbc2-4175-a653-00e46e2de3a1.aspx</guid>
      <link>http://www.vpsw.com/blogbaby/PermaLink,guid,c163aa6c-bbc2-4175-a653-00e46e2de3a1.aspx</link>
      <pubDate>Fri, 30 Mar 2007 22:12:15 GMT</pubDate>
      <description>&lt;p&gt;
There are four (development) life annoyances that I can do without:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Recruiters who only use the state abbreviation to describe a job location. "Urgent
need for Senior .NET Developer, Location: CA"&lt;/li&gt;
&lt;li&gt;
Forum posters who demand code for entire applications. "Please send me chat server
code -- urgent."&lt;/li&gt;
&lt;li&gt;
Repeated requests for Interview Questions.&amp;nbsp; &lt;a href="http://community.strongcoders.com/blogs/vpsw/archive/2006/10/23/the-only-interview-question-you-ll-ever-need-to-answer-click-here.aspx"&gt;I've
covered this elsewhere.&lt;/a&gt;
&lt;br&gt;
&lt;/li&gt;
&lt;li&gt;
Lazy gits who can't be bothered to learn how to read either C# or VB.NET. "Thanks
for the answer, but my project is in VB.NET, I don't understand C#."&lt;/li&gt;
&lt;/ol&gt;
At least once a week, I'll answer a question on forum somewhere with a code example
and get a "Thank you, but" response.&amp;nbsp; Often accompanied by a request to rewrite
the code in their language of choice.&amp;nbsp; With perfectly named variables and smilies
in the comments.&lt;br&gt;
&lt;br&gt;
This burns my toast.&amp;nbsp; It takes enormous willpower not to simply respond "find
another job you lazy git". 
&lt;br&gt;
&lt;br&gt;
A) We're never talking more than 50 lines of code, usually it is around 20.&amp;nbsp; 
&lt;br&gt;
B) 3/4 of the friggin' code is manipulating &lt;b&gt;.NET Framework objects&lt;/b&gt; using &lt;b&gt;.NET
Framework methods&lt;/b&gt; and &lt;b&gt;.NET Framework properties&lt;/b&gt; -- which are -- wait for
it...&lt;u&gt;&lt;font color="#ff0000" size="4"&gt;
&lt;br&gt;
&lt;br&gt;
THE SAME FOR BOTH C# and VB.NET!&lt;/font&gt;&lt;/u&gt;
&lt;br&gt;
&lt;br&gt;
So this post is a (no longer) quick and dirty guide for figuring out how to translate
C# into VB.NET (and vice versa, but frankly 92.6% of the time its a VB coder who complains).&amp;nbsp;
It will become my standard response for all the future lazy gits.&lt;br&gt;
&lt;br&gt;
Let's start at the top (of the class file that is)...&lt;br&gt;
&lt;br&gt;
Need to reference a namespace...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: using System.Data.SqlClient;&lt;/font&gt;
&lt;br&gt;
&lt;font color="#008000"&gt;ala VB: Imports System.Data.SqlClient&lt;br&gt;
&lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt;Note the ubiquitous semicolon (&lt;b&gt;;&lt;/b&gt;).&amp;nbsp; C# statements can span
pages like a sentence in &lt;a href="http://www.online-literature.com/james_joyce/ulysses/"&gt;Ulysses&lt;/a&gt;.&amp;nbsp;
They don't end until the ; appears. VB statements get one line to do their business,
unless they are ended with the awkward _ line continuation (underscore) which allows
them to continue one more line unless they are ended with the awkward _, repeat.&lt;br&gt;
&lt;br&gt;
A class...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: public class TheClassINeverHad&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; //fields, methods and properties
-- oh my!&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;ala VB: Public Class TheClassINeverHad&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; 'fields, methods and properties
-- oh my!&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; End Class&lt;br&gt;
&lt;/font&gt;&lt;/blockquote&gt; Ooooh no, C# does everything in lower case! (and its compiler
is very strict about keeping it that way)&lt;br&gt;
VB Capitalizes! (not that its compiler cares)&lt;br&gt;
&lt;br&gt;
In C#, all code blocks are marked with with brackets{}. 
&lt;br&gt;
In VB, code blocks usually go until a line that starts with End followed by the type
of code block, which iin this case is Class.&lt;br&gt;
&lt;br&gt;
Fancier class declarations...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: public abstract class TheClassINeverHad&lt;/font&gt;
&lt;br&gt;
&lt;font color="#008000"&gt;ala VB: Public MustInherit Class TheClassINeverHad&lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt; &lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: public sealed class TheClassINeverHad&lt;/font&gt;
&lt;br&gt;
&lt;font color="#008000"&gt;ala VB: Public NotInheritable Class TheClassINeverHad&lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt;Why VB.NET couldn't use the more common OOP vernacular is beyond me.&lt;br&gt;
&lt;br&gt;
Interface declarations...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: public interface IPractical&lt;/font&gt;
&lt;br&gt;
&lt;font color="#008000"&gt;ala VB: Public Interface IPractical&lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt;Hooray, that should be clear even to the laziest git.&lt;br&gt;
&lt;br&gt;
Extending a class...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: public class TheClassINeverHad: APracticalClass&lt;/font&gt;
&lt;br&gt;
&lt;font color="#008000"&gt;ala VB: Public Class TheClassINeverHad&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Inherits APracticalClass&lt;br&gt;
&lt;/font&gt;&lt;/blockquote&gt;The humble colon does a lot here in C#.&amp;nbsp; The VB syntax leaves
nothing to doubt.&lt;br&gt;
&lt;br&gt;
Implementing an interface...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: public class TheClassINeverHad: IPractical&lt;/font&gt;
&lt;br&gt;
&lt;font color="#008000"&gt;ala VB: Public Class TheClassINeverHad&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Implements IPractical&lt;br&gt;
&lt;/font&gt;&lt;/blockquote&gt;or interfaces...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: public class TheClassINeverHad: IPractical,
IRidiculous&lt;/font&gt;
&lt;br&gt;
&lt;font color="#008000"&gt;ala VB: Public Class TheClassINeverHad&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Implements IPractical&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Implements IRidiculous&lt;br&gt;
&lt;/font&gt;&lt;/blockquote&gt;The colon does everything!&amp;nbsp; 
&lt;br&gt;
&lt;br&gt;
Extending and implementing...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: public class TheClassINeverHad: APracticalClass,
IPractical, IRidiculous&lt;/font&gt;
&lt;br&gt;
&lt;font color="#008000"&gt;ala VB: Public Class TheClassINeverHad&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Inherits APracticalClass&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;
Implements IPractical&lt;/font&gt;
&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; Implements
IRidiculous&lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt; A comment...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: //This is a 1 line comment&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* This starts a multiline comment&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; This ends a multiline comment */&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;ala VB: 'This is a one line comment&lt;br&gt;
&lt;/font&gt;&lt;/blockquote&gt;There is no such thing as a multline comment in VB, but who comments
code anyway?&lt;br&gt;
&lt;br&gt;
You really should though.&lt;br&gt;
&lt;br&gt;
a field...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: private int SomeNumberIWillUse;&lt;/font&gt;
&lt;br&gt;
&lt;font color="#008000"&gt;ala VB: Private SomeNumberIWillUse as Integer&lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt; VB.NET surrounds the name of the variable with its access modifier and
type.&amp;nbsp; C# gets all that out of the way then tells you the name.&lt;br&gt;
&lt;br&gt;
a constant...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: private const string LAZY_GIT = "Lazy Git";&lt;/font&gt;
&lt;br&gt;
&lt;font color="#008000"&gt;ala VB: Private Const LAZY_GIT as String = "Lazy Git"&lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt;a constructor...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: public TheClassINeverHad()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&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; //Do Something
Useful&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;ala VB: public Sub New()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; 'Do Something Useful&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; End Sub&lt;br&gt;
&lt;/font&gt;&lt;/blockquote&gt; &lt;font color="#008000"&gt;
&lt;br&gt;
&lt;/font&gt;C# uses the name of the class to indicate the constructor. The Sub New in VB
is a little clearer at first blush.&lt;br&gt;
&lt;br&gt;
A structure can be a handy little doo-dad when a class is overkill...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: public struct Soda&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&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; public
string Name;&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; public int
Calories;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;ala VB: Public Structure Soda&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Public Name as String&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Public Calories as Integer&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; End Structure&lt;br&gt;
&lt;/font&gt;&lt;/blockquote&gt; More brackets in C#, another End statement in VB. C# shows it
inclination for abbreviation. Patterns develop.&lt;br&gt;
&lt;br&gt;
Let's not forget enumerations...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: public enum PlanetValues&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&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;
Mercury = 0,&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;
Venus = 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;
Earth = 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;&amp;nbsp;&amp;nbsp;
Mars = 3,&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;
Jupiter = 4,&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;
Saturn = 5,&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;
Uranus = 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;&amp;nbsp;&amp;nbsp;
Neptune = 7,&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;
Pluto = 8&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;br&gt;
&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
public enum PlanetValues&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&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;
Mercury,&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;
Venus,&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;
Earth,&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;
Mars,&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;
Jupiter,&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;
Saturn,&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;
Uranus,&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;
Neptune,&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;
Pluto&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;/font&gt;
&lt;br&gt;
&lt;font color="#008000"&gt;ala VB: Public Enum PlanetValues&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Mercury = 0&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Venus = 1&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Earth = 2&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Mars = 3&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Jupiter = 4&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Saturn = 5&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Uranus = 6&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Neptune = 7&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Pluto = 8&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; End Enum&lt;br&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Public Enum PlanetValues&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Mercury 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Venus 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Earth 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Mars 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Jupiter 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Saturn 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Uranus 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Neptune 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Pluto 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; End Enum&lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt;All these enumerations are identical.&amp;nbsp; If no value for the first
element is specified it is set = 0, every other unspecified element is incremented
one from the previous element. Curiously the C# syntax uses commas and not semi-colons.&lt;br&gt;
&lt;br&gt;
a local variable...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: string DeveloperPersona;&lt;/font&gt;
&lt;br&gt;
&lt;font color="#008000"&gt;ala VB: Dim DeveloperPersona as String&lt;/font&gt;&lt;font color="#008000"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;/blockquote&gt;arrays...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: string[] CoolDevTools;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; string[] CoolDevTools = new string[5];&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //assignment&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; CoolDevTools[0] = SomeString;&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;ala VB: Dim CoolDevTools as String()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Dim CoolDevTools(5) as String&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; 'assignment&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; CoolDevTools(0) = SomeString&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt;C# uses square brackets [] for the elements.&lt;br&gt;
VB uses parentheses ().&lt;br&gt;
&lt;br&gt;
Ditto for collection elements...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: AnObjectType SomeObject = (&lt;/font&gt;&lt;font color="#0000ff"&gt;AnObjectType)&lt;/font&gt;&lt;font color="#0000ff"&gt;SomeHashtable[SomeKey];&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; A&lt;/font&gt;&lt;font color="#0000ff"&gt;nObjectType
SomeObject = (&lt;/font&gt;&lt;font color="#0000ff"&gt;AnObjectType)&lt;/font&gt;&lt;font color="#0000ff"&gt;SomeArrayList[SomeIndex];&lt;/font&gt;&lt;font color="#0000ff"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;ala VB:&amp;nbsp; Dim SomeObject as AnObjectType = SomeHashtable(SomeKey)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="#008000"&gt;Dim
SomeObject as AnObjectType = SomeArrayList(SomeIndex)&lt;/font&gt;
&lt;br&gt;
&lt;font color="#008000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; 'or if Option
Strict is on&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; D&lt;/font&gt;&lt;font color="#008000"&gt;im SomeObject
as AnObjectType = CType(SomeHashtable(SomeKey), AnObjectType)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="#008000"&gt;Dim SomeObject
as AnObjectType = &lt;/font&gt;&lt;font color="#008000"&gt;CType(&lt;/font&gt;&lt;font color="#008000"&gt;SomeArrayList(SomeIndex)&lt;/font&gt;&lt;font color="#008000"&gt;,
AnObjectType)&lt;/font&gt;
&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; &lt;/font&gt;&lt;/blockquote&gt;C#
doesn't do narrowing implicit type casts,&amp;nbsp; so an element retrieved from an untyped
collection must be explicitly cast.&amp;nbsp; This is done by wrapping the object type
in parentheses and smooshing it against the collection name.&lt;br&gt;
VB will implicitly cast unless &lt;a href="http://msdn2.microsoft.com/en-us/library/zcd4xwzs%28vs.71%29.aspx"&gt;Option
Strict &lt;/a&gt;is On, in which case the CType method must be used to cast the element
returned to the proper type.&lt;br&gt;
&lt;br&gt;
a method that does NOT return a value...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: public void ThePerfectMethod(string DeveloperName)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; {&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; // coding goodness&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;ala VB: Public Sub ThePerfectMethod(DeveloperName as
String)&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; 'Coding Goodness&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; End Sub&lt;br&gt;
&lt;/font&gt;&lt;/blockquote&gt;a method that does return a value...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: public int ThePerfectMethod(string DeveloperName)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; {&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; // coding goodness&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;
return 42;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;ala VB: Public Function ThePerfectMethod(DeveloperName
as String) as Integer&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; 'Coding Goodness&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; Return 42&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; End Function&lt;br&gt;
&lt;/font&gt;&lt;/blockquote&gt; As with fields and constants, C# states the access modifier and
the type being returned by the method before getting to the name.&amp;nbsp; When nothing
is returned the type is &lt;b&gt;void&lt;/b&gt;.&lt;br&gt;
VB has separate keywords to differentiate between methods that return nada (Sub) and
those that return something (Function).&lt;br&gt;
Parameters are types just like variables are in each language:&amp;nbsp; type Name in
C#, Name as Type in VB.&lt;br&gt;
&lt;br&gt;
a read/write property...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: public int TheAnswer&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; get{&amp;nbsp;&amp;nbsp;
return mTheAnswer;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; set{&amp;nbsp; mTheAnswer
= value;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;ala VB: Public Property TheAnswer() as Integer&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; Get&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;
Return mTheAnswer&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; End Get&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; Set (Value
as Integer)&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;
mTheAnswer = Value&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; End Set&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;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; End Property&lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt;a read-only property...&lt;br&gt;
&lt;blockquote&gt;&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: public int TheAnswer&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; get{&amp;nbsp;&amp;nbsp;
return mTheAnswer;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;ala VB: Public ReadOnly Property TheAnswer() as Integer&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; Get&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;
Return mTheAnswer&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; End Get&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; End Property&lt;br&gt;
&lt;/font&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;a write-only property...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: public int TheAnswer&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; set{&amp;nbsp; mTheAnswer
= value;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;ala VB: Public WriteOnly Property TheAnswer() as Integer&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; Set (Value
as Integer)&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;
mTheAnswer = Value&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; End Set&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;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; End Property&lt;/font&gt;&lt;/blockquote&gt;VB.NET
needs to be explicity told a property is read- or write-only, C# is happy as long
as there is a get or set -- it figures it out.&lt;br&gt;
&lt;br&gt;
static(Shared) members...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: private static int mANumberEveryoneNeeds;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; public static ANumberEveryoneNeeds&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&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; get{return &lt;/font&gt;&lt;font color="#0000ff"&gt;mANumberEveryoneNeeds;}&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; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void ResetTheNumber()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&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; &lt;/font&gt;&lt;font color="#0000ff"&gt;mANumberEveryoneNeeds
= 0;&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; }&lt;br&gt;
&lt;/font&gt; &lt;font color="#008000"&gt;ala VB: Private Shared mANumberEveryonNeeds as Integer&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Public Readonly Shared Property
ANumberEveryoneNeeds() as Integer&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; Get&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;
Return mANumberEveryoneNeeds&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; End Get&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; End Property&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Public Shared Sub ResetTheNumber
()&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;
mANumberEveryoneNeeds = 0&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; End Sub&lt;br&gt;
&lt;/font&gt;&lt;/blockquote&gt;
&lt;br&gt;
Shared = static.&amp;nbsp; static = Shared. Static members are shared by ALL instances
of a class.&amp;nbsp; The meaning of static is not as immediately a clear as Shared. But
it's not that hard to remember.&lt;br&gt;
&lt;br&gt;
Branching...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: if(SomeVariable == 42)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; {&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; Answer = "That's
it!";&lt;br&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; HasWisdom = true;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; {&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; Answer = "That's
not it.";&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;
HasWisdon = false;&lt;br&gt;
&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; //one line syntax&lt;br&gt;
&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; if(SomeVariable
== 42)&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; Answer = "That's
it!";&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; else&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; Answer = "That's
not it.";&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;/font&gt;
&lt;br&gt;
&lt;font color="#0000ff"&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;ala VB: If SomeVariable = 42 Then&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Answer = "That's it!"&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; HasWisdom
= True&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Else&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Answer = "That's not it."&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; HasWisdom
= False&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; End if&lt;br&gt;
&lt;/font&gt;&lt;/blockquote&gt;There's no Then in C#, the boolean expression is wrapped in parentheses
and the code to execute is within {}. The brackets are not required if the condition
only executes one line.&amp;nbsp; Like most other constructs in VB, the code block ends
with a uniquely named End statement: End If. 
&lt;br&gt;
&lt;br&gt;
Note in C# the == is an evaluation operator, as opposed to the assignment operator
=.&amp;nbsp; In VB = performs both tasks. 
&lt;br&gt;
&lt;br&gt;
What fun is an If statement without boolean logic...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: if(!Page.IsPostBack) //Not operator&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="#0000ff"&gt;if(Night
!= Day) //Inequality&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="#0000ff"&gt;if(Night
== Day &amp;amp; Pigs.CurrentState == PigState.Flying) // And&lt;/font&gt;
&lt;br&gt;
&lt;font color="#0000ff"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; if(&lt;/font&gt;&lt;font color="#0000ff"&gt;Night
== Day &amp;amp;&amp;amp; Pigs.CurrentState == PigState.Flying&lt;/font&gt;&lt;font color="#0000ff"&gt;)
//Conditional And&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="#0000ff"&gt;if(Night
== Day | Pigs.CurrentState == PigState.Flying) // Or&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="#0000ff"&gt;if(Night
== Day || Pigs.CurrentState == PigState.Flying) // Conditional Or&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="#0000ff"&gt;if(Night
== Day ^ Pigs.CurrentState == PigState.Flying) // Xor&lt;/font&gt;
&lt;br&gt;
&lt;br&gt;
&lt;font color="#0000ff"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;ala VB: If Not Page.IsPostBack Then&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; If Night &amp;lt;&amp;gt; Day Then 'Inequality&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If Night = Day And Pigs.CurrentState
= PigState.Flying Then 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="#008000"&gt;If
Night = Day AndAlso Pigs.CurrentState = PigState.Flying Then 'Conditional And&lt;/font&gt;
&lt;br&gt;
&lt;font color="#008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; If Night
= Day Or Pigs.CurrentState = PigState.Flying Then 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="#008000"&gt;If
Night = Day OrElse Pigs.CurrentState = PigState.Flying Then 'Conditional Or&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="#008000"&gt;If
Night = Day Xor Pigs.CurrentState = PigState.Flying Then&lt;/font&gt;
&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; 
&lt;br&gt;
&lt;/font&gt;&lt;/blockquote&gt;VB spells everything out, though &amp;lt;&amp;gt; is a unique feature
of the language.&amp;nbsp; The conditional operators AndAlso (&amp;amp;&amp;amp;) and OrElse(||)
are tres useful, they short circuit the code and stop evaluting as soon as the appropriate
condition is met. 
&lt;br&gt;
&lt;br&gt;
And when If Then is isn't enough...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: &lt;/font&gt;&lt;font color="#0000ff"&gt;switch(SelectedPlanet)&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; {&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; case
PlanetValues.Earth:&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;
message = "Live there";&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;
break;&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; case
PlanetValues.Venus:&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; case
PlanetValues.Mars:&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; message = "Landed there";&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; break;&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; &lt;/font&gt;&lt;font color="#0000ff"&gt;case
PlanetValues.Mercury:&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; case
PlanetValues.Jupiter:&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; case
PlanetValues.Saturn:&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; case
PlanetValues.Uranus:&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; case
PlanetValues.Neptune:&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; message = "Flew by";&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; break;&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; case
PlanetValues.Pluto:&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; message = "Is it a planet?"&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; break;&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;
default:&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; message = "Never heard of it";&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; break;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;font color="#0000ff"&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;/font&gt;&lt;font color="#0000ff"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;ala VB: Select Case SelectedPlanet&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; Case PlanetValues.Earth&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;
message = "Live there"&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; Case PlanetValues.Venus,
PlanetValues.Mars&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;
message = "Landed there"&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; Case PlanetValues.Mercury,
PlanetValues.Jupiter, PlanetValues.Saturn, PlanetValues.Uranus, PlanetValues.Neptune&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;
message = "Flew by"&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; Case PlanetValues.Pluto&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;
message = "Is it a planet?"&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; Case Else&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;
message = "Never heard of it"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; End Select&lt;/font&gt;&lt;font color="#008000"&gt;&lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt;In C#, there's only one value per case, but once a supplied value matches
a case, the code will "fall through" until it finds a case that executes code.&amp;nbsp;
All cases that have code must end with a break;. 
&lt;br&gt;
In VB, multiple values can be present on a line, it's also possible to do &lt;a href="http://msdn2.microsoft.com/en-us/library/cy37t14y%28VS.71%29.aspx"&gt;ranges.&lt;/a&gt; The
code cannot fall through in VB, but the extra flexibility for defining case values
makes it unecessary. 
&lt;br&gt;
&lt;br&gt;
For Loops...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: for(int Index = 0; Index &amp;lt; SomeIntegerArray.Length;
Index ++)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; {&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; Total
+= SomeIntegerArray[Index];&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; CallSomeOtherFunction(SomeIntegerArray[Index]);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; //A single line For Loop
can be done without the brackets&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; &lt;/font&gt;&lt;font color="#0000ff"&gt;for(int
Index = 0; Index &amp;lt; SomeIntegerArray.Length; Index ++)&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; &lt;/font&gt;&lt;font color="#0000ff"&gt;Total
+= SomeIntegerArray[Index];&lt;br&gt;
&lt;/font&gt;&lt;font color="#0000ff"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;ala VB: For Index as Integer = 0 to SomeIntegerArray.Length
-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; Total += SomeIntegerArray(Index)&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; CallSomeOtherFunction(SomeIntegerArray(Index))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Next&lt;/font&gt;&lt;/blockquote&gt;
&lt;br&gt;
In C#, {} brackets define what code gets looped, but a single line statement does
not require brackets. Iteration step size is always specified&lt;br&gt;
VB always requires the Next statement.&amp;nbsp; The iteration step size defaults to 1
for VB, to change the iteration step size...&lt;br&gt;
&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: for(int Index = 0; Index &amp;lt; SomeIntegerArray.Length;
Index += 2)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; {&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; Total
+= SomeIntegerArray[Index];&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; CallSomeOtherFunction(SomeIntegerArray[Index]);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;/font&gt;&lt;font color="#0000ff"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#0000ff"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;ala VB: For Index as Integer = 0 to SomeIntegerArray.Length
-1 Step 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; Total += SomeIntegerArray(Index)&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; &lt;/font&gt;&lt;font color="#008000"&gt;CallSomeOtherFunction(SomeIntegerArray(Index))&lt;/font&gt;
&lt;br&gt;
&lt;font color="#008000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Next&lt;/font&gt;&lt;/blockquote&gt;To
break out of the loop before it completes...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: for(int Index = 0; Index &amp;lt; SomeIntegerArray.Length;
Index += 2)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; {&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; Total
+= SomeIntegerArray[Index];&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; if(CallSomeOtherFunction(SomeIntegerArray[Index])
== false)&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;
break;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;font color="#0000ff"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#0000ff"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;ala VB: For Index as Integer = 0 to SomeIntegerArray.Length
-1 Step 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; Total += SomeIntegerArray(Index)&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; If &lt;/font&gt;&lt;font color="#008000"&gt;CallSomeOtherFunction(SomeIntegerArray(Index))
= False Then&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;
Exit For&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; End if&lt;br&gt;
&lt;/font&gt; &lt;font color="#008000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Next&lt;/font&gt;&lt;/blockquote&gt;break
is used to get out of every kind of loop in C#.&amp;nbsp; The command for exiting a loop
in VB.NET depends on the type of the loop. This can come in handy for nested loops
of different types.&lt;br&gt;
&lt;br&gt;
For each loops...&lt;br&gt;
&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: foreach(Universe PossibleUniverse in PossibleUniverses)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; {&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; if(PossibleUniverse.HasStrongForce)&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; {&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;
&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; AddToViableCandidates(PossibleUniverse);&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; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;/font&gt;&lt;font color="#0000ff"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#0000ff"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;ala VB: For Each PossibleUniverse as Universe in PossibleUniverses 
&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; If PossibleUniverse.HasStrongForce
Then&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;
AddToViableCandidates(PossibleUniverse)&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; End if&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Next&lt;br&gt;
&lt;br&gt;
&lt;/font&gt;&lt;/blockquote&gt;Ignore the brackets and the for each loops look a lot alike.&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
Do While Loops...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: do&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; {&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; Total
+= SomeIntegerArray[Index];&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; if(CallSomeOtherFunction(SomeIntegerArray[Index])
== false)&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;
break;&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; Index++;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; while(Index &amp;lt; SomeIntegerArray.Length);&lt;br&gt;
&lt;/font&gt;&lt;font color="#0000ff"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;ala VB: Do&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; Total += SomeIntegerArray(Index)&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; If &lt;/font&gt;&lt;font color="#008000"&gt;CallSomeOtherFunction(SomeIntegerArray(Index))
= False Then&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;
Exit Do&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; End if&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;
Index += 1&lt;br&gt;
&lt;/font&gt; &lt;font color="#008000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Loop While
Index &amp;lt; SomeIntegerArray.Length&lt;br&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; Do &lt;/font&gt;&lt;font color="#008000"&gt;While
Index &amp;lt; SomeIntegerArray.Length&lt;/font&gt;
&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;&amp;nbsp;
Total += SomeIntegerArray(Index)&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; If &lt;/font&gt;&lt;font color="#008000"&gt;CallSomeOtherFunction(SomeIntegerArray(Index))
= False Then&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;
Exit Do&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; End if&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; Index += 1&lt;br&gt;
&lt;/font&gt; &lt;font color="#008000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Loop &lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt;
&lt;br&gt;
The do loop in C# always executes at least once.&amp;nbsp; The top version of the VB loop
does as well.&amp;nbsp; While the second version evaluates the condition before executing.
This is the one of the few code structures in VB that doesn't denote it's end using
an End statement (the others being the for and for each loops). If it did it would
look something like this...&lt;br&gt;
&lt;font color="#ff1493"&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; 'This is not legal syntax -- just what
a Do loop would look like if VB were maddeningly consistent&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Do&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; Total +=SomeIntegerArray(Index)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End Do While Index &amp;lt; SomeIntegerArray.Length&lt;br&gt;
&lt;/font&gt;
&lt;br&gt;
Which is just goofy.&lt;br&gt;
&lt;br&gt;
Do Until Loops...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: do&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; {&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; Total
+= SomeIntegerArray[Index];&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; if(CallSomeOtherFunction(SomeIntegerArray[Index])
== false)&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;
break;&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; Index++;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; while(Index &amp;lt; SomeIntegerArray.Length);&lt;br&gt;
&lt;/font&gt;&lt;font color="#0000ff"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;ala VB: Do&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; Total += SomeIntegerArray(Index)&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; If &lt;/font&gt;&lt;font color="#008000"&gt;CallSomeOtherFunction(SomeIntegerArray(Index))
= False Then&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;
Exit Do&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; End if&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; Index += 1&lt;br&gt;
&lt;/font&gt; &lt;font color="#008000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Loop Until
Index = SomeIntegerArray.Length&lt;br&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; Do &lt;/font&gt;&lt;font color="#008000"&gt;Until
Index = SomeIntegerArray.Length&lt;/font&gt;
&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;&amp;nbsp;
Total += SomeIntegerArray(Index)&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; If &lt;/font&gt;&lt;font color="#008000"&gt;CallSomeOtherFunction(SomeIntegerArray(Index))
= False Then&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;
Exit Do&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; End if&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; Index += 1&lt;br&gt;
&lt;/font&gt; &lt;font color="#008000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Loop &lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt; 
&lt;br&gt;
Wait a second -- there's no &lt;b&gt;do until&lt;/b&gt; in C#. &lt;b&gt;Until&lt;/b&gt; is just the other
side of &lt;b&gt;while&lt;/b&gt;.&amp;nbsp; Instead of executing &lt;b&gt;while&lt;/b&gt; a condition is true,
it executes &lt;b&gt;until&lt;/b&gt; it is true. When moving from VB.NET to C# just use the while
and flip the condition to its opposite. Again the C# loop and the first VB loop execute
at least once.&amp;nbsp; 
&lt;br&gt;
&lt;br&gt;
And the last loop is the plain old while loop...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: &lt;/font&gt;&lt;font color="#0000ff"&gt;while(Index
&amp;lt; SomeIntegerArray.Length)&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; {&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; Total
+= SomeIntegerArray[Index];&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; if(CallSomeOtherFunction(SomeIntegerArray[Index])
== false)&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;
break;&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; Index++;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;/font&gt;&lt;font color="#0000ff"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;ala VB: While &lt;/font&gt;&lt;font color="#008000"&gt;Index &amp;lt;
SomeIntegerArray.Length&lt;br&gt;
&lt;/font&gt;
&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;&amp;nbsp;
Total += SomeIntegerArray(Index)&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; If &lt;/font&gt;&lt;font color="#008000"&gt;CallSomeOtherFunction(SomeIntegerArray(Index))
= False Then&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;
Exit While&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; End if&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; Index += 1&lt;br&gt;
&lt;/font&gt; &lt;font color="#008000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; End&amp;nbsp;
While 
&lt;br&gt;
&lt;/font&gt;&lt;font color="#008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="#008000"&gt;&lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt; While loops in both languages evaluate the condition before executing.&amp;nbsp;
Note the while uses the familiar Exit While to break and the End While to terminate
the loop.&lt;br&gt;
&lt;br&gt;
Finally, a tricky difference -- hooking up event handlers...&lt;br&gt;
&lt;blockquote&gt;&lt;font color="#0000ff"&gt;ala C#: &lt;/font&gt;&lt;font color="#0000ff"&gt;SomeButton.Click
+= new ButtonEventHandler(SomeButton_Click);&lt;/font&gt;&lt;font color="#0000ff"&gt;&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; &lt;/font&gt;
&lt;br&gt;
&lt;font color="#008000"&gt;ala VB: AddHandler SomeButton.Click, AddressOf SomeButton_Click&lt;/font&gt;
&lt;br&gt;
&lt;br&gt;
&lt;font color="#008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; 'or directly declare
it&lt;/font&gt;
&lt;br&gt;
&lt;font color="#008000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; Sub SomeButton_Click(ByVal
sender As System.Object, ByVal e As System.EventArgs) Handles SomeButton.Click&lt;/font&gt;
&lt;br&gt;
&lt;/blockquote&gt;VB lets you hook up the Handler on the event declaration or add the handler
dynamically.&amp;nbsp; C# only allows the dynamic hook.&amp;nbsp; 
&lt;br&gt;
&lt;br&gt;
I think this post has sufficiently covered 93.7% of commonly encountered code.&amp;nbsp;
I'd cover &lt;a href="http://msdn2.microsoft.com/en-us/library/512aeb7t.aspx"&gt;Generics&lt;/a&gt; (&lt;a href="http://msdn2.microsoft.com/en-us/library/ms379608%28vs.80%29.aspx"&gt;VB
usage)&lt;/a&gt;&amp;nbsp; but I think anyone working with Generics probably doesn't have any
problems reading either language.&lt;br&gt;
&lt;br&gt;
Here are some reference links...&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://msdn2.microsoft.com/en-us/library/6a71f45d.aspx"&gt;C# Operators&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://msdn2.microsoft.com/en-us/library/x53a06bb.aspx"&gt;C# Keywords&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://msdn2.microsoft.com/en-us/library/ksh7h19t%28VS.71%29.aspx"&gt;VB.NET
Keywords&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsintro7/html/vxgrfLanguageEquivalents.asp"&gt;Language
Equivalents&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
And for the truly lazy or people who have to translate more than 20 lines of code,
there are converters (though you might get some &lt;a href="http://www.vpsw.com/blogbaby/PermaLink,guid,bb634e82-a78f-4fca-9d5d-a63616d70f99.aspx"&gt;interesting
results&lt;/a&gt;) ...&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.tangiblesoftwaresolutions.com/"&gt;Tanglible Software&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.developerfusion.co.uk/utilities/convertcsharptovb.aspx"&gt;Developer
Fusion&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.google.com/search?q=c%23+vb+converter&amp;amp;sourceid=navclient-ff&amp;amp;ie=UTF-8&amp;amp;rlz=1B3GGGL_enUS176US213&amp;amp;aq=t"&gt;Or
Google For More&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
So learn 'em both -- double your code examples, double your employment opportunities
-- double your fun.&lt;br&gt;
&lt;img width="0" height="0" src="http://www.vpsw.com/blogbaby/aggbug.ashx?id=c163aa6c-bbc2-4175-a653-00e46e2de3a1" /&gt;</description>
      <comments>http://www.vpsw.com/blogbaby/CommentView,guid,c163aa6c-bbc2-4175-a653-00e46e2de3a1.aspx</comments>
      <category>.NET</category>
      <category>2.0</category>
      <category>Annoyances</category>
    </item>
    <item>
      <trackback:ping>http://www.vpsw.com/blogbaby/Trackback.aspx?guid=525bb927-f195-40af-8d0f-c160edd00d45</trackback:ping>
      <pingback:server>http://www.vpsw.com/blogbaby/pingback.aspx</pingback:server>
      <pingback:target>http://www.vpsw.com/blogbaby/PermaLink,guid,525bb927-f195-40af-8d0f-c160edd00d45.aspx</pingback:target>
      <dc:creator>Dean</dc:creator>
      <wfw:comment>http://www.vpsw.com/blogbaby/CommentView,guid,525bb927-f195-40af-8d0f-c160edd00d45.aspx</wfw:comment>
      <wfw:commentRss>http://www.vpsw.com/blogbaby/SyndicationService.asmx/GetEntryCommentsRss?guid=525bb927-f195-40af-8d0f-c160edd00d45</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In the <a href="http://www.vpsw.com/blogbaby/PermaLink,guid,33ff2980-8f72-432b-b214-8c0423d76168.aspx">previous
GridView post</a>, we figured out how to create a simple updating GridView without
a lick of code.  But it only updated a value from a TextBox, nothing
too difficult about that.  What would happen if one of the columns needed
a DropDownList for editing purposes?  This is something that required code in
ASP.NET 1.1. The DropDownList needed to be bound in the ItemDataBound event,
and that was only for display purposes.  Updating required even more code. 
Can the declarative code model handle this twist without resulting to actual -- gasp
-- coding?
</p>
        <p>
I'll save the suspense and admit that, in fact, it is possible to create an Editable,
Updating GridView with a DropDownList  without writing any code.  Here
it is.   We'll talk about the interesting bits afterwards.
</p>
        <p>
          <font color="#0000ff" face="Courier New">    &lt;div&gt;<br />
       &lt;asp:GridView ID="GridViewDropDown" runat="server"
DataSourceID="TestSqlSource" AutoGenerateEditButton="True" DataKeyNames="NameID" AutoGenerateColumns="False"
&gt;<br />
       &lt;Columns&gt;<br />
        &lt;asp:BoundField HeaderText="Name" DataField="Name" 
/&gt;</font>
        </p>
        <p>
          <font color="#0000ff" face="Courier New">          
&lt;asp:TemplateField HeaderText="Popularity Trend"&gt;<br />
              
&lt;EditItemTemplate&gt;<br />
                  
&lt;asp:DropDownList ID="PopularityTrendDropDown" runat="server"   SelectedValue='&lt;%#
Bind("PopularityID") %&gt;' DataSourceID="PopularitySqlSource" DataTextField="Description" 
DataValueField="PopularityID" &gt;&lt;/asp:DropDownList&gt;<br />
                                     
<br />
              
&lt;/EditItemTemplate&gt;<br />
              
&lt;ItemTemplate&gt;<br />
                  
&lt;asp:Label ID="PopularityTrendLabel" runat="server" Text='&lt;%# Eval("Description")
%&gt;'&gt;&lt;/asp:Label&gt;<br />
              
&lt;/ItemTemplate&gt;<br />
           &lt;/asp:TemplateField&gt;<br />
    
<br />
       &lt;/Columns&gt;<br />
        &lt;/asp:GridView&gt;<br />
        &lt;asp:SqlDataSource ID="TestSqlSource"
runat="server" ConnectionString="&lt;%$ ConnectionStrings:TestConnectionString %&gt;"
SelectCommand="SELECT Name, NameID, PopularityID, Description FROM [BabyName] bn Left
join Popularity p on bn.PopularityID = p.PopularityID" UpdateCommand="UPDATE BabyName
SET Name = @Name, PopularityID = @PopularityID WHERE NameID = @NameID"  &gt;<br />
                    
<br />
        &lt;/asp:SqlDataSource&gt;<br />
         &lt;asp:SqlDataSource ID="PopularitySqlSource"
runat="Server" ConnectionString="&lt;%$ ConnectionStrings:TestConnectionString %&gt;"
SelectCommand="SELECT PopularityID, [Description] FROM [Popularity]" &gt;</font>
        </p>
        <p>
          <font color="#0000ff" face="Courier New">        
&lt;/asp:SqlDataSource&gt;<br />
  
<br />
    &lt;/div&gt;</font>
        </p>
        <p>
There are now 2 data sources, one for the GridView, and the <font color="#0000ff" face="Courier New">PopularitySqlSource </font>for
the PopularityTrendDropDown. The PopularitySqlSource just provides a simple list
of the possible values to display in the dropdown. <font color="#0000ff" face="Courier New">TestSqlSource'</font>s
SelectCommand has a new join and and an extra column, Description.  This is so
that the Item template can display the user friendly text value in the label. 
I was searching for a sexier way of doing this, so I didn't have to include the join
and column in the statement, but heck, as long as we're polluting the aspx with SQL
statements might as well use all the SQL we can.
</p>
        <p>
In order to use a DropDown in the GridView, we need to stop autogenerating the columns
and create a TemplateField for the column that has the DropDown.   The TemplateField
has two parts: the ItemTemplate and the EditItemTemplate.  The ItemTemplate simply
shows the user friendly description of the PopularityTrend.  The EditItemTemplate
holds the DropDownList for selecting the proper PopularityID. Whatever is in the EditItemTemplate
is what shows up when the user clicks on the Edit button.
</p>
        <p>
There is a little bit of <a href="http://msdn2.microsoft.com/en-us/library/ms178366.aspx">data
binding script syntax </a>needed to properly bind the underlying values into the controls. 
For the DropDownList we bind the SelectedValue to the PopularityID...
</p>
        <p>
          <font color="#0000ff" face="Courier New">SelectedValue='&lt;%# Bind("PopularityID")
%&gt;'</font>
        </p>
        <p>
The bit bewteen &lt;%# and %&gt; is actually a call to the Bind method which
sets up the control to do two-way binding so that it can keep track of updates. 
This is used behind the scenes for the BoundField too.  Technically this is coding,
but since we are not creating a separate code file or breaking out the &lt;script&gt;
tags, we'll ignore it.
</p>
        <p>
Similarly the Text property of the label is bound using the Eval method.  
</p>
        <p>
          <font color="#0000ff" face="Courier New">Text='&lt;%# Eval("Description") %&gt;'</font>
        </p>
        <p>
The difference between Eval and Bind, is that Eval is a read-only binding, it can't
be used to update the underlying datasource.
</p>
        <p>
So all that is needed to create a GridView that uses a DropDownList to edit a column
value is:
</p>
        <ol>
          <li>
A TemplateField to hold the DropDown when a row is being edited, and a label when
it is not 
</li>
          <li>
A DataSource for the list portion of the DropDown control 
</li>
          <li>
A little extra SQL to get the friendly description for the label 
</li>
          <li>
A wee bit of binding <strike>code</strike> syntax</li>
        </ol>
        <p>
So, still no code, but our GridView and DataSource declarations are getting
heftier.  Probably still slimmer than the analogous code, but not nearly as compact
as the simple GridView from the previous example. 
</p>
        <p>
Actually, if there were a DropDownField available the declarative syntax could be
almost as slim as it was for the simple GridView.  I'm surprised that there wasn't
a DropDownField class created for ASP.NET 2.0 given their frequent use for editing
grid columns.  I'm sure someone has created one (or is is <a href="http://blogs.msdn.com/mattdotson/articles/490868.aspx">creating
one</a>) that could be added in. Could be a fun little project.
</p>
        <p>
Next time, we'll see if we can add in multi-row editing without code.  I have
my doubts.
</p>
        <p>
 
</p>
        <p>
 
</p>
        <img width="0" height="0" src="http://www.vpsw.com/blogbaby/aggbug.ashx?id=525bb927-f195-40af-8d0f-c160edd00d45" />
      </body>
      <title>Looking For More Trouble</title>
      <guid isPermaLink="false">http://www.vpsw.com/blogbaby/PermaLink,guid,525bb927-f195-40af-8d0f-c160edd00d45.aspx</guid>
      <link>http://www.vpsw.com/blogbaby/PermaLink,guid,525bb927-f195-40af-8d0f-c160edd00d45.aspx</link>
      <pubDate>Thu, 08 Feb 2007 04:20:59 GMT</pubDate>
      <description>&lt;p&gt;
In the&amp;nbsp;&lt;a href="http://www.vpsw.com/blogbaby/PermaLink,guid,33ff2980-8f72-432b-b214-8c0423d76168.aspx"&gt;previous
GridView post&lt;/a&gt;, we figured out how to create a simple updating GridView without
a lick of code.&amp;nbsp; But&amp;nbsp;it only updated a&amp;nbsp;value from a TextBox, nothing
too difficult about that.&amp;nbsp; What would happen if one of the columns&amp;nbsp;needed
a DropDownList for editing purposes?&amp;nbsp; This is something that required code in
ASP.NET 1.1.&amp;nbsp;The DropDownList needed to be bound in the ItemDataBound event,
and that was only for display purposes.&amp;nbsp; Updating required even more code.&amp;nbsp;
Can the declarative code model handle this twist without resulting to actual -- gasp
-- coding?
&lt;/p&gt;
&lt;p&gt;
I'll save the suspense and admit that, in fact, it is possible to create an&amp;nbsp;Editable,
Updating&amp;nbsp;GridView with a DropDownList&amp;nbsp; without writing any code.&amp;nbsp; Here
it is.&amp;nbsp;&amp;nbsp; We'll talk about the interesting bits afterwards.
&lt;/p&gt;
&lt;p&gt;
&lt;font color="#0000ff" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;div&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:GridView ID="GridViewDropDown" runat="server"
DataSourceID="TestSqlSource" AutoGenerateEditButton="True" DataKeyNames="NameID" AutoGenerateColumns="False"
&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Columns&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:BoundField HeaderText="Name" DataField="Name"&amp;nbsp;
/&amp;gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font color="#0000ff" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;asp:TemplateField HeaderText="Popularity Trend"&amp;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;lt;EditItemTemplate&amp;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;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;asp:DropDownList ID="PopularityTrendDropDown" runat="server"&amp;nbsp;&amp;nbsp; SelectedValue='&amp;lt;%#
Bind("PopularityID") %&amp;gt;' DataSourceID="PopularitySqlSource" DataTextField="Description"&amp;nbsp;
DataValueField="PopularityID" &amp;gt;&amp;lt;/asp:DropDownList&amp;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;&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; 
&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;lt;/EditItemTemplate&amp;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;lt;ItemTemplate&amp;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;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;asp:Label ID="PopularityTrendLabel" runat="server" Text='&amp;lt;%# Eval("Description")
%&amp;gt;'&amp;gt;&amp;lt;/asp:Label&amp;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;lt;/ItemTemplate&amp;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;lt;/asp:TemplateField&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Columns&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/asp:GridView&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:SqlDataSource ID="TestSqlSource"
runat="server" ConnectionString="&amp;lt;%$ ConnectionStrings:TestConnectionString %&amp;gt;"
SelectCommand="SELECT Name, NameID, PopularityID, Description FROM [BabyName] bn Left
join Popularity p on bn.PopularityID = p.PopularityID" UpdateCommand="UPDATE BabyName
SET Name = @Name, PopularityID = @PopularityID WHERE NameID = @NameID"&amp;nbsp; &amp;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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/asp:SqlDataSource&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:SqlDataSource ID="PopularitySqlSource"
runat="Server" ConnectionString="&amp;lt;%$ ConnectionStrings:TestConnectionString %&amp;gt;"
SelectCommand="SELECT PopularityID, [Description] FROM [Popularity]" &amp;gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font color="#0000ff" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;/asp:SqlDataSource&amp;gt;&lt;br&gt;
&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/div&amp;gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
There are now 2 data sources, one for the GridView, and the &lt;font color="#0000ff" face="Courier New"&gt;PopularitySqlSource &lt;/font&gt;for
the PopularityTrendDropDown.&amp;nbsp;The PopularitySqlSource just provides a simple list
of the possible values&amp;nbsp;to display in the dropdown.&amp;nbsp;&lt;font color="#0000ff" face="Courier New"&gt;TestSqlSource'&lt;/font&gt;s
SelectCommand has a new join and and an extra column, Description.&amp;nbsp; This is so
that the Item template can display the user friendly text value in the label.&amp;nbsp;
I was searching for a sexier way of doing this, so I didn't have to include the join
and column in the statement, but heck, as long as we're polluting the aspx with SQL
statements might as well use all the SQL we can.
&lt;/p&gt;
&lt;p&gt;
In order to use a DropDown in the GridView, we need to stop autogenerating the columns
and create a TemplateField for the column that has the DropDown.&amp;nbsp;&amp;nbsp; The TemplateField
has two parts: the ItemTemplate and the EditItemTemplate.&amp;nbsp; The ItemTemplate simply
shows the user friendly description of the PopularityTrend.&amp;nbsp; The EditItemTemplate
holds the DropDownList for selecting the proper PopularityID. Whatever is in the EditItemTemplate
is what shows up when the user clicks on the Edit button.
&lt;/p&gt;
&lt;p&gt;
There is a little bit of &lt;a href="http://msdn2.microsoft.com/en-us/library/ms178366.aspx"&gt;data
binding script syntax &lt;/a&gt;needed to properly bind the underlying values into the controls.&amp;nbsp;
For the DropDownList we bind the SelectedValue to the PopularityID...
&lt;/p&gt;
&lt;p&gt;
&lt;font color="#0000ff" face="Courier New"&gt;SelectedValue='&amp;lt;%# Bind("PopularityID")
%&amp;gt;'&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
The bit bewteen &amp;lt;%# and&amp;nbsp;%&amp;gt; is actually a call to the Bind method which
sets up the control to do two-way binding so that it can keep track of updates.&amp;nbsp;
This is used behind the scenes for the BoundField too.&amp;nbsp; Technically this is coding,
but since we are not creating a separate code file or breaking out the &amp;lt;script&amp;gt;
tags, we'll ignore it.
&lt;/p&gt;
&lt;p&gt;
Similarly the&amp;nbsp;Text property of the label is bound using the Eval method.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
&lt;font color="#0000ff" face="Courier New"&gt;Text='&amp;lt;%# Eval("Description") %&amp;gt;'&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
The difference between Eval and Bind, is that Eval is a read-only binding, it can't
be used to update the underlying datasource.
&lt;/p&gt;
&lt;p&gt;
So all that is needed to create a GridView that uses a DropDownList to edit a column
value is:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
A TemplateField to hold the DropDown when a row is being edited, and a label when
it is not 
&lt;/li&gt;
&lt;li&gt;
A DataSource for the list portion of the DropDown control 
&lt;/li&gt;
&lt;li&gt;
A little extra SQL to get the friendly description for the label 
&lt;/li&gt;
&lt;li&gt;
A wee bit of binding &lt;strike&gt;code&lt;/strike&gt; syntax&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
So, still no code, but our GridView and DataSource declarations&amp;nbsp;are&amp;nbsp;getting
heftier.&amp;nbsp; Probably still slimmer than the analogous code, but not nearly as compact
as the simple GridView from the previous example. 
&lt;/p&gt;
&lt;p&gt;
Actually, if there were a DropDownField available the declarative syntax could be
almost as slim as it was for the simple GridView.&amp;nbsp; I'm surprised that there wasn't
a DropDownField class created for ASP.NET 2.0 given their frequent use for editing
grid columns.&amp;nbsp; I'm sure someone has created one (or is is &lt;a href="http://blogs.msdn.com/mattdotson/articles/490868.aspx"&gt;creating
one&lt;/a&gt;) that could be added in. Could be a fun little project.
&lt;/p&gt;
&lt;p&gt;
Next time, we'll see if we can add in multi-row editing without code.&amp;nbsp; I have
my doubts.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.vpsw.com/blogbaby/aggbug.ashx?id=525bb927-f195-40af-8d0f-c160edd00d45" /&gt;</description>
      <comments>http://www.vpsw.com/blogbaby/CommentView,guid,525bb927-f195-40af-8d0f-c160edd00d45.aspx</comments>
      <category>2.0</category>
      <category>GridView</category>
      <category>SqlDataSource</category>
    </item>
    <item>
      <trackback:ping>http://www.vpsw.com/blogbaby/Trackback.aspx?guid=33ff2980-8f72-432b-b214-8c0423d76168</trackback:ping>
      <pingback:server>http://www.vpsw.com/blogbaby/pingback.aspx</pingback:server>
      <pingback:target>http://www.vpsw.com/blogbaby/PermaLink,guid,33ff2980-8f72-432b-b214-8c0423d76168.aspx</pingback:target>
      <dc:creator>Dean</dc:creator>
      <wfw:comment>http://www.vpsw.com/blogbaby/CommentView,guid,33ff2980-8f72-432b-b214-8c0423d76168.aspx</wfw:comment>
      <wfw:commentRss>http://www.vpsw.com/blogbaby/SyndicationService.asmx/GetEntryCommentsRss?guid=33ff2980-8f72-432b-b214-8c0423d76168</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Starting to get more questions about <a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.aspx">GridViews</a> and <a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.sqldatasource.aspx">SqlDataSources</a> on
the forums I haunt.  On the surface, these two components seem to offer a quick
path to application development with no coding.  
</p>
        <p>
And sure enough, once you figure them out, you don't have to do much to get an updatable
GridView on the page.
</p>
        <p>
Here's an example of a fully updating GridView...
</p>
        <blockquote dir="ltr" style="margin-right: 0px;">
          <p dir="ltr" style="margin-right: 0px;">
            <font color="#0000ff" face="Courier New">&lt;asp:GridView ID="NoCodeGridView" runat="server"
DataSourceID="TestSqlSource" AutoGenerateEditButton="True"   DataKeyNames="NameID"&gt;<br />
&lt;/asp:GridView&gt;<br /></font>
          </p>
          <p>
            <font color="#0000ff" face="Courier New">&lt;asp:SqlDataSource ID="TestSqlSource"
runat="server" ConnectionString="&lt;%$ ConnectionStrings:TestConnectionString %&gt;"
SelectCommand="SELECT * FROM [BabyName]" </font>
            <font color="#0000ff" face="Courier New">UpdateCommand="UPDATE
BabyName SET Name = @Name WHERE NameID = @NameID"&gt;<br />
            &lt;UpdateParameters&gt;<br />
               
&lt;asp:Parameter Name="Name" Size="50" Type="String" /&gt;<br />
               
&lt;asp:Parameter Name="NameID" Type="Int32" /&gt;<br />
            &lt;/UpdateParameters&gt;<br />
 &lt;/asp:SqlDataSource&gt;</font>
          </p>
        </blockquote>
        <p>
The code behind file is strangely empty, yet clicking on a row's edit button
brings up an editable row with an update and cancel button.  And clicking on
the update button saves the altered baby name.  This scares and frightens
me, because I know it won't be this easy once I need to do something real. While
I appreciate that the details of implementation have been hidden from me, the
fact that I can't see them also worries me. I'll leave that aside for the moment. I
will also ignore the fact that I have embedded SQL statements in an ASPX page, and
we'll move on and examine what's needed so the snippet above works.
</p>
        <p>
The key in the GridView is this attribute:
</p>
        <font color="#ff0000" size="2">
        </font>
        <blockquote dir="ltr" style="margin-right: 0px;">
          <p>
            <font color="#ff0000" size="2">
              <font color="#0000ff" face="Courier New">AutoGenerateEditButton="True" </font>
            </font>
          </p>
        </blockquote>
        <p>
This tells the GridView to generate the Edit button and Update/Cancel button. There
are other ways to do this, but we're looking for the quickest, dirtiest way at the
moment.
</p>
        <p>
The real keys are in the SqlDataSource.  Without a select command nothing
would be bound to the grid. And it obviously needs an update command, otherwise you
get this exception...
</p>
        <blockquote dir="ltr" style="margin-right: 0px;">
          <h2>
            <i>
              <font size="3">Updating is not supported by data source 'TestSqlSource' unless
UpdateCommand is specified.</font>
            </i>
          </h2>
        </blockquote>
        <p>
Reading the stack trace for the exception shows you what ASP.NET is doing behind the
scenes. 
</p>
        <blockquote dir="ltr" style="margin-right: 0px;">
          <p>
            <font color="#008000">
              <font face="Courier New">
                <font color="#ff1493">
                  <font color="#ff0000">  
System.Web.UI.WebControls.SqlDataSourceView.ExecuteUpdate(IDictionary keys, IDictionary
values, IDictionary oldValues) +1828259<br />
   System.Web.UI.DataSourceView.Update(IDictionary keys, IDictionary values,
IDictionary oldValues,    DataSourceViewOperationCallback callback)
+78<br />
   System.Web.UI.WebControls.GridView.HandleUpdate(GridViewRow row, Int32
rowIndex, Boolean causesValidation) +1215<br />
   </font>
                  <font color="#008000">System.Web.UI.WebControls.GridView.HandleEvent(EventArgs
e, Boolean causesValidation, String validationGroup) +858</font>
                  <br />
                </font>   System.Web.UI.WebControls.GridView.OnBubbleEvent(Object source,
EventArgs e) +95<br />
   System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
+35<br />
   System.Web.UI.WebControls.GridViewRow.OnBubbleEvent(Object source, EventArgs
e) +117<br />
   System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
+35<br />
   System.Web.UI.WebControls.LinkButton.OnCommand(CommandEventArgs e) +115<br />
   System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument)
+163<br />
   System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String
eventArgument) +7<br />
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl,
String eventArgument) +11<br />
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +174<br />
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint,
Boolean includeStagesAfterAsyncPoint) +5102</font>
              <br />
            </font>
          </p>
        </blockquote>
        <p>
The last three are the interesting ones (the stack reads down from the last method
called to the first).  The GridView's HandleEvent figures out an Update is going
on and calls HandleUpdate, which in turn calls the Update method on the DataSourceView,
which in turn calls the ExecuteUpdate on the SqlDataSourceView which does the real
work.  
</p>
        <p>
Let's take a little side trip and see what we can find out about these methods.
</p>
        <p>
GridView.HandleUpdate is not a public method and hence does not appear in the documentation.
</p>
        <p>
DataSourceView.Update is <a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.datasourceview.update.aspx">public</a>. 
DataSourceView is an abstract base class that alll the DataSourceView implementations
are derived from.  This method calls the protected ExecuteUpdate method on that
has been implemented by the inheriting class, in this case <a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.sqldatasourceview.aspx">SqlDataSourceView</a>.<a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.sqldatasourceview.aspx">ExecuteUpdate</a>.
All pretty straightforward, and the SqlDataSourceView has some event handlers so it
looks like there are places to hook in when actual programming is required.
</p>
        <p>
Let's end our little side trip and get back into seeing what's needed for the little
snippet to work.
</p>
        <p>
One thing I noted was the documentation frequently mentions parameters, so they must
be needed to make this work.  Let's pull out the &lt;UpdateParameters&gt; element
and see what happens.
</p>
        <p>
          <a href="http://www.m-w.com/cgi-bin/dictionary?va=begorra">Begorra</a>! The GridView does
not throw an error and still updates.  It seems everything will be peachy if
the update command parameter names correspond to columns in the select command. Let's
run a wee test and change a parameter name in the update command. @Name will become
@Name1
</p>
        <p>
Didn't like that all
</p>
        <blockquote dir="ltr" style="margin-right: 0px;">
          <h2>
            <font size="3">
              <em>Must declare the variable '@Name1'.</em>
            </font>
          </h2>
        </blockquote>
        <p>
So this is all you actually need...
</p>
        <p>
    <font color="#0000ff" face="Courier New"> &lt;asp:GridView
ID="NoCodeGridView" runat="server" DataSourceID="TestSqlSource" AutoGenerateEditButton="True"
DataKeyNames="NameID"&gt;<br />
     &lt;/asp:GridView&gt;<br />
     &lt;asp:SqlDataSource ID="TestSqlSource" runat="server" ConnectionString="&lt;%$
ConnectionStrings:TestConnectionString %&gt;" SelectCommand="SELECT * FROM [BabyName]"
UpdateCommand="UPDATE BabyName SET Name = @Name WHERE NameID = @NameID"&gt;<br />
         
<br />
     &lt;/asp:SqlDataSource&gt;</font></p>
        <p>
As long as the SqlDataSource's SelectCommand returns column names that correspond
to the parameter names used in the UpdateCommand it all works.
</p>
        <p>
Next time we'll see what happens when you need to do something a little fancier.
</p>
        <img width="0" height="0" src="http://www.vpsw.com/blogbaby/aggbug.ashx?id=33ff2980-8f72-432b-b214-8c0423d76168" />
      </body>
      <title>Here Comes Trouble</title>
      <guid isPermaLink="false">http://www.vpsw.com/blogbaby/PermaLink,guid,33ff2980-8f72-432b-b214-8c0423d76168.aspx</guid>
      <link>http://www.vpsw.com/blogbaby/PermaLink,guid,33ff2980-8f72-432b-b214-8c0423d76168.aspx</link>
      <pubDate>Wed, 31 Jan 2007 03:18:17 GMT</pubDate>
      <description>&lt;p&gt;
Starting to get more questions about &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.aspx"&gt;GridViews&lt;/a&gt; and &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.sqldatasource.aspx"&gt;SqlDataSources&lt;/a&gt;&amp;nbsp;on
the forums I haunt.&amp;nbsp; On the surface, these two components seem to offer a quick
path to application development with no coding.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
And sure enough, once you figure them out, you don't have to do much to get an updatable
GridView on the page.
&lt;/p&gt;
&lt;p&gt;
Here's an example of a fully updating GridView...
&lt;/p&gt;
&lt;blockquote dir="ltr" style="margin-right: 0px;"&gt; 
&lt;p dir="ltr" style="margin-right: 0px;"&gt;
&lt;font color="#0000ff" face="Courier New"&gt;&amp;lt;asp:GridView ID="NoCodeGridView" runat="server"
DataSourceID="TestSqlSource" AutoGenerateEditButton="True"&amp;nbsp;&amp;nbsp; DataKeyNames="NameID"&amp;gt;&lt;br&gt;
&amp;lt;/asp:GridView&amp;gt;&lt;br&gt;
&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font color="#0000ff" face="Courier New"&gt;&amp;lt;asp:SqlDataSource ID="TestSqlSource"
runat="server" ConnectionString="&amp;lt;%$ ConnectionStrings:TestConnectionString %&amp;gt;"
SelectCommand="SELECT * FROM [BabyName]" &lt;/font&gt;&lt;font color="#0000ff" face="Courier New"&gt;UpdateCommand="UPDATE
BabyName SET Name = @Name WHERE NameID = @NameID"&amp;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;lt;UpdateParameters&amp;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;
&amp;lt;asp:Parameter Name="Name" Size="50" Type="String" /&amp;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;
&amp;lt;asp:Parameter Name="NameID" Type="Int32" /&amp;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;lt;/UpdateParameters&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;lt;/asp:SqlDataSource&amp;gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
The code behind file is strangely empty, yet clicking on&amp;nbsp;a row's&amp;nbsp;edit button
brings up an editable row with an update and cancel button.&amp;nbsp; And clicking on
the update button saves the&amp;nbsp;altered baby name.&amp;nbsp; This scares and frightens
me, because I know it won't&amp;nbsp;be this easy once I need to do something real. While
I appreciate that the details of implementation have been hidden from me,&amp;nbsp;the
fact that I can't see them&amp;nbsp;also worries me. I'll leave that aside for the moment.&amp;nbsp;I
will also ignore the fact that I have embedded SQL statements in an ASPX page, and
we'll move on and examine what's needed so the snippet above works.
&lt;/p&gt;
&lt;p&gt;
The key in the GridView is this attribute:
&lt;/p&gt;
&lt;font color="#ff0000" size="2"&gt; &lt;/font&gt;&lt;blockquote dir="ltr" style="margin-right: 0px;"&gt; 
&lt;p&gt;
&lt;font color="#ff0000" size="2"&gt;&lt;font color="#0000ff" face="Courier New"&gt;AutoGenerateEditButton="True"&amp;nbsp;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
This tells the GridView to generate the Edit button and Update/Cancel button. There
are other ways to do this, but we're looking for the quickest, dirtiest way at the
moment.
&lt;/p&gt;
&lt;p&gt;
The real keys&amp;nbsp;are in the SqlDataSource.&amp;nbsp; Without a select command nothing
would be bound to the grid. And it obviously needs an update command, otherwise you
get this exception...
&lt;/p&gt;
&lt;blockquote dir="ltr" style="margin-right: 0px;"&gt; 
&lt;h2&gt;&lt;i&gt;&lt;font size="3"&gt;Updating is not supported by data source 'TestSqlSource' unless
UpdateCommand is specified.&lt;/font&gt;&lt;/i&gt; 
&lt;/h2&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Reading the stack trace for the exception shows you what ASP.NET is doing behind the
scenes.&amp;nbsp;
&lt;/p&gt;
&lt;blockquote dir="ltr" style="margin-right: 0px;"&gt; 
&lt;p&gt;
&lt;font color="#008000"&gt;&lt;font face="Courier New"&gt;&lt;font color="#ff1493"&gt;&lt;font color="#ff0000"&gt;&amp;nbsp;&amp;nbsp;
System.Web.UI.WebControls.SqlDataSourceView.ExecuteUpdate(IDictionary keys, IDictionary
values, IDictionary oldValues) +1828259&lt;br&gt;
&amp;nbsp;&amp;nbsp; System.Web.UI.DataSourceView.Update(IDictionary keys, IDictionary values,
IDictionary oldValues,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DataSourceViewOperationCallback callback)
+78&lt;br&gt;
&amp;nbsp;&amp;nbsp; System.Web.UI.WebControls.GridView.HandleUpdate(GridViewRow row, Int32
rowIndex, Boolean causesValidation) +1215&lt;br&gt;
&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="#008000"&gt;System.Web.UI.WebControls.GridView.HandleEvent(EventArgs
e, Boolean causesValidation, String validationGroup) +858&lt;/font&gt;
&lt;br&gt;
&lt;/font&gt;&amp;nbsp;&amp;nbsp; System.Web.UI.WebControls.GridView.OnBubbleEvent(Object source,
EventArgs e) +95&lt;br&gt;
&amp;nbsp;&amp;nbsp; System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
+35&lt;br&gt;
&amp;nbsp;&amp;nbsp; System.Web.UI.WebControls.GridViewRow.OnBubbleEvent(Object source, EventArgs
e) +117&lt;br&gt;
&amp;nbsp;&amp;nbsp; System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
+35&lt;br&gt;
&amp;nbsp;&amp;nbsp; System.Web.UI.WebControls.LinkButton.OnCommand(CommandEventArgs e) +115&lt;br&gt;
&amp;nbsp;&amp;nbsp; System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument)
+163&lt;br&gt;
&amp;nbsp;&amp;nbsp; System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String
eventArgument) +7&lt;br&gt;
&amp;nbsp;&amp;nbsp; System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl,
String eventArgument) +11&lt;br&gt;
&amp;nbsp;&amp;nbsp; System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +174&lt;br&gt;
&amp;nbsp;&amp;nbsp; System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint,
Boolean includeStagesAfterAsyncPoint) +5102&lt;/font&gt;
&lt;br&gt;
&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
The last three are the interesting ones (the stack reads down from the last method
called to the first).&amp;nbsp; The GridView's HandleEvent figures out an Update is going
on and calls HandleUpdate, which in turn calls the Update method on the DataSourceView,
which in turn calls the ExecuteUpdate on the SqlDataSourceView which does the real
work.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Let's take a little side trip and see what we can find out about these methods.
&lt;/p&gt;
&lt;p&gt;
GridView.HandleUpdate is not a public method and hence does not appear in the documentation.
&lt;/p&gt;
&lt;p&gt;
DataSourceView.Update&amp;nbsp;is &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.datasourceview.update.aspx"&gt;public&lt;/a&gt;.&amp;nbsp;
DataSourceView is an abstract base class that alll the DataSourceView implementations
are derived from.&amp;nbsp; This method calls the protected ExecuteUpdate method on that
has been implemented by the inheriting class, in this case &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.sqldatasourceview.aspx"&gt;SqlDataSourceView&lt;/a&gt;.&lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.sqldatasourceview.aspx"&gt;ExecuteUpdate&lt;/a&gt;.
All pretty straightforward, and the SqlDataSourceView has some event handlers so it
looks like there are places to hook in when actual programming is required.
&lt;/p&gt;
&lt;p&gt;
Let's end our little side trip and get back into seeing what's needed for the little
snippet to work.
&lt;/p&gt;
&lt;p&gt;
One thing I noted was the documentation frequently mentions parameters, so they must
be needed to make this work.&amp;nbsp; Let's pull out the &amp;lt;UpdateParameters&amp;gt; element
and see what happens.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.m-w.com/cgi-bin/dictionary?va=begorra"&gt;Begorra&lt;/a&gt;! The&amp;nbsp;GridView&amp;nbsp;does
not throw an error and still updates.&amp;nbsp; It seems everything will be peachy if
the update command parameter names correspond to columns in the select command. Let's
run a wee test and change a parameter name in the update command. @Name will become
@Name1
&lt;/p&gt;
&lt;p&gt;
Didn't like that all
&lt;/p&gt;
&lt;blockquote dir="ltr" style="margin-right: 0px;"&gt; 
&lt;h2&gt;&lt;font size="3"&gt;&lt;em&gt;Must declare the variable '@Name1'.&lt;/em&gt;&lt;/font&gt; 
&lt;/h2&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
So this is all you actually need...
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff" face="Courier New"&gt; &amp;lt;asp:GridView
ID="NoCodeGridView" runat="server" DataSourceID="TestSqlSource" AutoGenerateEditButton="True"
DataKeyNames="NameID"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/asp:GridView&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:SqlDataSource ID="TestSqlSource" runat="server" ConnectionString="&amp;lt;%$
ConnectionStrings:TestConnectionString %&amp;gt;" SelectCommand="SELECT * FROM [BabyName]"
UpdateCommand="UPDATE BabyName SET Name = @Name WHERE NameID = @NameID"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/asp:SqlDataSource&amp;gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
As long as the SqlDataSource's SelectCommand returns column names that correspond
to the parameter names used in the UpdateCommand it all works.
&lt;/p&gt;
&lt;p&gt;
Next time we'll see what happens when you need to do something a little fancier.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.vpsw.com/blogbaby/aggbug.ashx?id=33ff2980-8f72-432b-b214-8c0423d76168" /&gt;</description>
      <comments>http://www.vpsw.com/blogbaby/CommentView,guid,33ff2980-8f72-432b-b214-8c0423d76168.aspx</comments>
      <category>2.0</category>
      <category>GridView</category>
      <category>SqlDataSource</category>
    </item>
    <item>
      <trackback:ping>http://www.vpsw.com/blogbaby/Trackback.aspx?guid=3a714537-4f53-46da-af87-d52921f773e7</trackback:ping>
      <pingback:server>http://www.vpsw.com/blogbaby/pingback.aspx</pingback:server>
      <pingback:target>http://www.vpsw.com/blogbaby/PermaLink,guid,3a714537-4f53-46da-af87-d52921f773e7.aspx</pingback:target>
      <dc:creator>Dean</dc:creator>
      <wfw:comment>http://www.vpsw.com/blogbaby/CommentView,guid,3a714537-4f53-46da-af87-d52921f773e7.aspx</wfw:comment>
      <wfw:commentRss>http://www.vpsw.com/blogbaby/SyndicationService.asmx/GetEntryCommentsRss?guid=3a714537-4f53-46da-af87-d52921f773e7</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">Under ASP.NET 1.1, the ASP.NET engine is
not (by default) responsible for the application's image, style sheet, and javascript
files. These are served up directly by IIS. ASP.NET can be made responsible for these
file types by playing with the ISAPI file mappings and maybe creating an HttpHandler
or two.<br /><br />
This changes under ASP.NET 2.0.  The ASP.NET engine has responsibility for all
these file types and is called when a request for one is made. 
<br /><br />
So what?  The files get served, the application works, who cares if IIS or ASP.NET
does the work?<br /><br />
In many applications it wouldn't matter, but what happens if the application has been
secured in web.config like so...<br /><br />
&lt;authorization&gt;<br />
   &lt;deny users="?" /&gt;<br />
&lt;/authorization&gt;<br /><br />
... and an anonymous user tries to access the site and gets redirected to the login
page?<br /><br />
Under 1.1, since IIS was responsible for the css, javascript and image files, it wouldn't
matter -- the page would be served as expected, showing all the images and properly
referencing any stylesheets or script files.<br /><br />
Under 2.0, the anonymous user would see an unstyled page with blank image boxes. Any
javascript calls to referenced files won't work either. Why? Because ASP.NET isn't
going to serve up anything but the login page to an anonymous user -- because that
is what it was told to do.<br /><br />
This is great for security, but can be a little frustrating when you KNOW you put
the right path in for that image, and KNOW that the all h1 elements should be hot
pink  and all you see is an unformatted mess.<br /><br />
Fortunately it is very easy to work around this so the public pages on a secured site
show up properly.  All that needs to be done is to tell the application that
anonymous users are allowed to access the content in certain folders. This can be
done using a <a href="http://msdn2.microsoft.com/en-us/library/b6x6shw7.aspx">location
element</a> or two in the web.config file.  The following one allows anonymous
users to access content in the unsecured_images folder...<br /><br />
&lt;location path="unsecured_images"&gt;<br />
    &lt;system.web&gt;<br />
      &lt;authorization&gt;<br />
        &lt;allow users="*" /&gt;<br />
      &lt;/authorization&gt;<br />
    &lt;/system.web&gt;<br />
  &lt;/location&gt;<br /><br />
That's all there is to it. 
<br /><br /><br /><p></p><img width="0" height="0" src="http://www.vpsw.com/blogbaby/aggbug.ashx?id=3a714537-4f53-46da-af87-d52921f773e7" /></body>
      <title>Before You Go Insane...</title>
      <guid isPermaLink="false">http://www.vpsw.com/blogbaby/PermaLink,guid,3a714537-4f53-46da-af87-d52921f773e7.aspx</guid>
      <link>http://www.vpsw.com/blogbaby/PermaLink,guid,3a714537-4f53-46da-af87-d52921f773e7.aspx</link>
      <pubDate>Thu, 18 Jan 2007 03:29:44 GMT</pubDate>
      <description>Under ASP.NET 1.1, the ASP.NET engine is not (by default) responsible for the application's image, style sheet, and javascript files. These are served up directly by IIS. ASP.NET can be made responsible for these file types by playing with the ISAPI file mappings and maybe creating an HttpHandler or two.&lt;br&gt;
&lt;br&gt;
This changes under ASP.NET 2.0.&amp;nbsp; The ASP.NET engine has responsibility for all
these file types and is called when a request for one is made. 
&lt;br&gt;
&lt;br&gt;
So what?&amp;nbsp; The files get served, the application works, who cares if IIS or ASP.NET
does the work?&lt;br&gt;
&lt;br&gt;
In many applications it wouldn't matter, but what happens if the application has been
secured in web.config like so...&lt;br&gt;
&lt;br&gt;
&amp;lt;authorization&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp; &amp;lt;deny users="?" /&amp;gt;&lt;br&gt;
&amp;lt;/authorization&amp;gt;&lt;br&gt;
&lt;br&gt;
... and an anonymous user tries to access the site and gets redirected to the login
page?&lt;br&gt;
&lt;br&gt;
Under 1.1, since IIS was responsible for the css, javascript and image files, it wouldn't
matter -- the page would be served as expected, showing all the images and properly
referencing any stylesheets or script files.&lt;br&gt;
&lt;br&gt;
Under 2.0, the anonymous user would see an unstyled page with blank image boxes. Any
javascript calls to referenced files won't work either. Why? Because ASP.NET isn't
going to serve up anything but the login page to an anonymous user -- because that
is what it was told to do.&lt;br&gt;
&lt;br&gt;
This is great for security, but can be a little frustrating when you KNOW you put
the right path in for that image, and KNOW that the all h1 elements should be hot
pink&amp;nbsp; and all you see is an unformatted mess.&lt;br&gt;
&lt;br&gt;
Fortunately it is very easy to work around this so the public pages on a secured site
show up properly.&amp;nbsp; All that needs to be done is to tell the application that
anonymous users are allowed to access the content in certain folders. This can be
done using a &lt;a href="http://msdn2.microsoft.com/en-us/library/b6x6shw7.aspx"&gt;location
element&lt;/a&gt; or two in the web.config file.&amp;nbsp; The following one allows anonymous
users to access content in the unsecured_images folder...&lt;br&gt;
&lt;br&gt;
&amp;lt;location path="unsecured_images"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;system.web&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;authorization&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;allow users="*" /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/authorization&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/system.web&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;/location&amp;gt;&lt;br&gt;
&lt;br&gt;
That's all there is to it. 
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.vpsw.com/blogbaby/aggbug.ashx?id=3a714537-4f53-46da-af87-d52921f773e7" /&gt;</description>
      <comments>http://www.vpsw.com/blogbaby/CommentView,guid,3a714537-4f53-46da-af87-d52921f773e7.aspx</comments>
      <category>.NET</category>
      <category>2.0</category>
      <category>2.0 Conversion</category>
      <category>web.config</category>
    </item>
    <item>
      <trackback:ping>http://www.vpsw.com/blogbaby/Trackback.aspx?guid=27013c9f-ec59-4762-9569-462a9b6b6653</trackback:ping>
      <pingback:server>http://www.vpsw.com/blogbaby/pingback.aspx</pingback:server>
      <pingback:target>http://www.vpsw.com/blogbaby/PermaLink,guid,27013c9f-ec59-4762-9569-462a9b6b6653.aspx</pingback:target>
      <dc:creator>Dean</dc:creator>
      <wfw:comment>http://www.vpsw.com/blogbaby/CommentView,guid,27013c9f-ec59-4762-9569-462a9b6b6653.aspx</wfw:comment>
      <wfw:commentRss>http://www.vpsw.com/blogbaby/SyndicationService.asmx/GetEntryCommentsRss?guid=27013c9f-ec59-4762-9569-462a9b6b6653</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Finally! .NET 2.0 has been out for a year.  Finally found the time to move
our <a href="http://www.celadonlabs.com/probeity/login.aspx?demo=true">main application</a> to
2.0. It's been a bit of an adventure.  There are 12 class libraries, 2 server
control assemblies, a service, a web app and various utilities.  Two of the class
libraries are in C++, one managed, one native. The truly insane can read about the <a href="http://community.strongcoders.com/blogs/vpsw/archive/2006/11/14/a-journey-to-c-land.aspx">little
odyssey through those assemblies</a>.  Everything else is written in VB.NET.  
<br /><br />
The VB.NET class libraries converted easily.  The only issue was in the few classes
that performed XSL Transformations where I had to change a couple of deprecated method
calls.  <a href="http://www.vpsw.com/blogbaby/PermaLink,guid,5b40fbc8-2743-48a9-b9e8-d9e394ad4ba1.aspx">These
were no surprise</a>.  Other than that there were only warnings for untyped functions
or parameters (very naughty, and one of the dangers of working in VB with OPTION STRICT
OFF) and a surprising number of unused local variables.  
<br /><br />
The web application was a lot trickier than anticipated.  There are some <a href="http://msdn2.microsoft.com/en-us/library/ms379586%28VS.80%29.aspx">fundamental
differences</a> between 1.1 and 2.0 web applications. One of the significant changes
is in the coding model.  2.0 makes use of partial classes, so that a single class
can be created from separate files, this cleans some things up.  There are no
longer control declarations in the code-behind file, but it is a change.  
</p>
        <p>
Here is a very <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/conversionissuesasp_net.asp">handy
resource</a> that discusses most of the issues you will run into when converting from
1.1 to 2.0.  
<br /><br />
In the standard out-of-the-box VS2005, the project file for web applications has also
gone the way of the dodo, you create Web Site Projects.  Everything in the project
tree gets put into the application. Fortunately, there is a feature to exclude files,
which you will use. Since the Web Site Project includes ALL the files in
the directory tree, files that you excluded in your 1.1 project will suddenly reappear
like uncompilable ghosts in the 2.0 version. The other annoying "feature" is that
these projects spew forth an assembly for every folder in your application, and couple
of others for good measure, and the files are randomly named.  Hello deployment
fun -- I'm sure there's good reason for this, but it is not intuitively obvious, it
seems friggin' nutty.
</p>
        <p>
This application model had been fine for the smaller projects I had
converted, and I figured I would discover a way to deal with the assembly vomit, so
I pushed on assuming that I was moments away from having a our application working
in 2.0. 
</p>
        <p>
But it was not to be, this web application pushed the Web Site Project model over
the cliff of despair.
</p>
        <p>
The application has around 60 pages, 15 classes and 15 user controls spread
amongst 10 directories. Most of the heavy lifting is done in the underlying libraries. I
didn't think it was that large until I tried to compile it.  In VS 2003, it was
up and running in under a minute, in VS2005 it was 5+ minutes, and the sucker was
crashing every time I changed the base web page class that the pages inherited from. 
I lived with this for about a day, googling while it compiled or restarted, toggling
various settings, swearing and pruning previously exlcuded and unused pages ruthlessly.  
</p>
        <p>
After one seemingly eternal cycle of rebooting, I seriously considered asking
for a quad-core super box or retreating back to 1.1.  I decided to take one
more look around the web for a solution and I stumbled across this <a href="http://www.simple-talk.com/dotnet/asp.net/asp.net-2.0-and-vs-2005---you-win-some,-you-lose-some/">article</a>,
which in turn led me to discover an alternate model to this lunancy, the <a href="http://msdn2.microsoft.com/en-us/asp.net/aa336618.aspx">Web
Application Project</a>! It was the old 1.1 compilation model, complete with
a single assembly output -- hooray.  It required some VS update installations
and yet another conversion from my original 1.1 application, but in a few hours I
had a quickly compiling application.  Some testing and a small victory dance
later, and it was time to start ripping out the facacta hand-rolled page templates
and putting in the master pages!
</p>
        <p>
        </p>
        <hr />
        <br />
Just a reminder kids, always use source code control, especially when undertaking
a conversion.  It makes mistakes almost painless and recovery simple! 
<br /><hr size="2" width="100%" /><br /><font color="#ff0000">UPDATE:</font>  MS has shipped the <a href="http://msdn.microsoft.com/vstudio/support/vs2005sp1/default.aspx">first
service pack for VS 2005</a>. This includes the Web Application Projects. If you have
previously installed the Web Application update, you will have to uninstall it before
installing the service pack.<br /><p></p><p></p><img width="0" height="0" src="http://www.vpsw.com/blogbaby/aggbug.ashx?id=27013c9f-ec59-4762-9569-462a9b6b6653" /></body>
      <title>Moving On Up to 2.0</title>
      <guid isPermaLink="false">http://www.vpsw.com/blogbaby/PermaLink,guid,27013c9f-ec59-4762-9569-462a9b6b6653.aspx</guid>
      <link>http://www.vpsw.com/blogbaby/PermaLink,guid,27013c9f-ec59-4762-9569-462a9b6b6653.aspx</link>
      <pubDate>Thu, 21 Dec 2006 04:04:59 GMT</pubDate>
      <description>&lt;p&gt;
Finally! .NET 2.0 has been out for a year.&amp;nbsp; Finally found the time&amp;nbsp;to move
our &lt;a href="http://www.celadonlabs.com/probeity/login.aspx?demo=true"&gt;main application&lt;/a&gt; to
2.0. It's been a bit of an adventure.&amp;nbsp; There are 12 class libraries, 2 server
control assemblies, a service, a web app and various utilities.&amp;nbsp; Two of the class
libraries are in C++, one managed, one native. The truly insane can read about the &lt;a href="http://community.strongcoders.com/blogs/vpsw/archive/2006/11/14/a-journey-to-c-land.aspx"&gt;little
odyssey through those assemblies&lt;/a&gt;.&amp;nbsp; Everything else is written in VB.NET.&amp;nbsp; 
&lt;br&gt;
&lt;br&gt;
The VB.NET class libraries converted easily.&amp;nbsp; The only issue was in the few classes
that performed XSL Transformations where I had to change a couple of deprecated method
calls.&amp;nbsp; &lt;a href="http://www.vpsw.com/blogbaby/PermaLink,guid,5b40fbc8-2743-48a9-b9e8-d9e394ad4ba1.aspx"&gt;These
were no surprise&lt;/a&gt;.&amp;nbsp; Other than that there were only warnings for untyped functions
or parameters (very naughty, and one of the dangers of working in VB with OPTION STRICT
OFF) and a surprising number of unused local variables.&amp;nbsp; 
&lt;br&gt;
&lt;br&gt;
The web application was a&amp;nbsp;lot trickier than anticipated.&amp;nbsp; There are some &lt;a href="http://msdn2.microsoft.com/en-us/library/ms379586%28VS.80%29.aspx"&gt;fundamental
differences&lt;/a&gt; between 1.1 and 2.0 web applications. One of the significant changes
is in the coding model.&amp;nbsp; 2.0 makes use of partial classes, so that a single class
can be created from separate files, this cleans some things up.&amp;nbsp; There are no
longer control declarations in the code-behind file, but it is a change.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Here is a very &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/conversionissuesasp_net.asp"&gt;handy
resource&lt;/a&gt; that discusses most of the issues you will run into when converting from
1.1 to 2.0.&amp;nbsp; 
&lt;br&gt;
&lt;br&gt;
In the standard out-of-the-box VS2005, the project file for web applications has also
gone the way of the dodo, you create Web Site Projects.&amp;nbsp; Everything in the project
tree gets put into the application. Fortunately, there is a feature to exclude files,
which you will use. Since the Web Site Project includes&amp;nbsp;ALL the&amp;nbsp;files in
the directory tree, files that you excluded in your 1.1 project will suddenly reappear
like uncompilable ghosts in the 2.0 version. The other annoying "feature" is that
these projects spew forth an assembly for every folder in your application, and couple
of others for good measure, and the files are randomly named.&amp;nbsp; Hello deployment
fun -- I'm sure there's good reason for this, but it is not intuitively obvious, it
seems friggin' nutty.
&lt;/p&gt;
&lt;p&gt;
This&amp;nbsp;application&amp;nbsp;model&amp;nbsp;had been fine for the smaller projects I had
converted, and I figured I would discover a way to deal with the assembly vomit, so
I pushed on assuming that I was moments away from having a our application working
in 2.0. 
&lt;/p&gt;
&lt;p&gt;
But it was not to be, this web application pushed&amp;nbsp;the Web Site Project model&amp;nbsp;over
the cliff of despair.
&lt;/p&gt;
&lt;p&gt;
The&amp;nbsp;application has around 60 pages, 15 classes&amp;nbsp;and 15 user controls spread
amongst 10 directories.&amp;nbsp;Most of the heavy lifting is done in the underlying libraries.&amp;nbsp;I
didn't think it was that large until I tried to compile it.&amp;nbsp; In VS 2003, it was
up and running in under a minute, in VS2005 it was 5+ minutes, and the sucker was
crashing every time I changed the base web page class that the pages inherited from.&amp;nbsp;
I lived with this for about a day, googling while it compiled or restarted, toggling
various settings, swearing and pruning previously exlcuded and unused pages ruthlessly.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
After one seemingly eternal cycle of rebooting, I&amp;nbsp;seriously considered asking
for a quad-core super box or retreating back to 1.1.&amp;nbsp;&amp;nbsp;I decided to take&amp;nbsp;one
more look around the web&amp;nbsp;for a solution and&amp;nbsp;I stumbled across this &lt;a href="http://www.simple-talk.com/dotnet/asp.net/asp.net-2.0-and-vs-2005---you-win-some,-you-lose-some/"&gt;article&lt;/a&gt;,
which in turn led me to&amp;nbsp;discover an alternate model to this lunancy, the &lt;a href="http://msdn2.microsoft.com/en-us/asp.net/aa336618.aspx"&gt;Web
Application Project&lt;/a&gt;!&amp;nbsp;It was the old 1.1 compilation model, complete with
a single assembly output -- hooray.&amp;nbsp; It required some VS update installations
and yet another conversion from my original 1.1 application, but in a few hours I
had a quickly compiling application.&amp;nbsp; Some testing and&amp;nbsp;a small victory dance
later, and it was time to start ripping out the facacta hand-rolled page templates
and putting in the master pages!
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;hr&gt;
&lt;br&gt;
Just a reminder kids, always use source code control, especially when undertaking
a conversion.&amp;nbsp; It makes mistakes almost painless and recovery simple! 
&lt;br&gt;
&lt;hr size="2" width="100%"&gt;
&lt;br&gt;
&lt;font color="#ff0000"&gt;UPDATE:&lt;/font&gt;&amp;nbsp; MS has shipped the &lt;a href="http://msdn.microsoft.com/vstudio/support/vs2005sp1/default.aspx"&gt;first
service pack for VS 2005&lt;/a&gt;. This includes the Web Application Projects. If you have
previously installed the Web Application update, you will have to uninstall it before
installing the service pack.&lt;br&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.vpsw.com/blogbaby/aggbug.ashx?id=27013c9f-ec59-4762-9569-462a9b6b6653" /&gt;</description>
      <comments>http://www.vpsw.com/blogbaby/CommentView,guid,27013c9f-ec59-4762-9569-462a9b6b6653.aspx</comments>
      <category>.NET</category>
      <category>2.0</category>
      <category>2.0 Conversion</category>
    </item>
  </channel>
</rss>