{"id":5163,"date":"2007-11-21T01:24:16","date_gmt":"2007-11-21T01:24:16","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vbteam\/2007\/11\/21\/hidden-gems-in-visual-basic-2008-amanda-silver\/"},"modified":"2024-07-05T14:38:06","modified_gmt":"2024-07-05T21:38:06","slug":"hidden-gems-in-visual-basic-2008-amanda-silver","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/vbteam\/hidden-gems-in-visual-basic-2008-amanda-silver\/","title":{"rendered":"Hidden Gems in Visual Basic 2008 (Amanda Silver)"},"content":{"rendered":"<p>Yesterday I <a href=\"http:\/\/blogs.msdn.com\/vbteam\/archive\/2007\/11\/19\/visual-basic-2008-ships.aspx\">promised to post<\/a> about the hidden gems in Visual Basic and Visual Studio 2008 that you haven&#8217;t read about in blog posts or seen at conferences. I forgot that I mentioned a few of my favorite features in the <a href=\"http:\/\/blogs.msdn.com\/vbteam\/archive\/2007\/04\/19\/visual-basic-orcas-beta1-is-in-the-wild.aspx\">Beta1 announcement<\/a> where I showed off the improvements in the Intellisense experience &#8211; statement completion for keywords, local variables, and expressions. In that post, I also cover a new language feature called Relaxed Delegates which allows you to provide alternate signatures for events. Both of those are pretty great features &#8211; but I promised to tell you about some <i>new <\/i>stuff.<\/p>\n<p>I polled the team and we came up with the following top ten that weren&#8217;t mentioned in my previous post. There&#8217;s so much I <i>could <\/i>talk about &#8211; but you&#8217;re going to have to check back. But first, I have to start with a keynote feature&#8230; <\/p>\n<h5><b>0) <\/b><b>Multi-targetting<\/b><\/h5>\n<p>In short, multi-targetting allows you to use Visual Studio 2008 (and VB 9!) to target the .NET 2.0 frameworks. All of the following features I&#8217;ll show you can be leveraged even if you&#8217;re targeting .NET 2.0! (With the exception of items #5 &amp; #7 as they depend on the LINQ to Objects and LINQ to XML APIs which reside in .NET 3.5) To do this, when you start up Visual Studio and create a new project, just make sure that the target framework is set to .NET Framework 2.0. <\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/clip_image002_2.jpg\"><img decoding=\"async\" style=\"border-right: 0px;border-top: 0px;border-left: 0px;border-bottom: 0px\" height=\"161\" alt=\"clip_image002\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/11\/clip_image002_thumb.jpg\" width=\"628\" border=\"0\" \/><\/a><\/p>\n<p>Note that projects you&#8217;re upgrading, will automatically target .NET Framework 2.0 until you add references to .NET 3.0 or 3.5 assemblies. <\/p>\n<h5><b>1) <\/b><b>Type Inference<\/b><\/h5>\n<p>In Visual Basic 9, in the following bit of code and NOTHING is late-bound &#8211; everything is bound at compile-time which means you get Intellisense and type checking.<\/p>\n<pre class=\"code\">        <span>Dim<\/span> dialog = <span>New<\/span> OpenFileDialog()\n        <span>Dim<\/span> result = dialog.ShowDialog()\n        <span>Dim<\/span> printStr = <span>&quot;C:&quot;\n<\/span>        <span>If<\/span> result = Windows.Forms.DialogResult.OK <span>Then\n<\/span>            printStr = dialog.FileName\n        <span>End<\/span> <span>If\n<\/span>        MsgBox(printStr)<\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<p>This makes prototyping very quick, easy, and type-safe! This feature and the mechanisms that control it are comprehensively covered in <a href=\"http:\/\/msdn.microsoft.com\/msdnmag\/issues\/07\/10\/BasicInstincts\/default.aspx\">this article by a member of our QA team, Bill Horst<\/a>. <\/p>\n<h5><b>2) <\/b><b>If Operator<\/b><\/h5>\n<p>Ever notice that the IIF function returns something of type Object? This means that you don&#8217;t get Intellisense or type-checking by default on that result. For those of you that <i>insist<\/i> on type-safe, early-bound code, you have to <i>cast<\/i> the result. The code then looks something like this:<\/p>\n<pre class=\"code\">        <span>Dim<\/span> intC <span>As<\/span> <span>Integer<\/span> = <span>CInt<\/span>(IIf(intA = intB, intA, intB - 1))<\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<p>With the If operator, you can now write that line as:<\/p>\n<pre class=\"code\">        <span>Dim<\/span> intD <span>As<\/span> <span>Integer<\/span> = <span>If<\/span>(intA = intB, intA, intB)<\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<p>And with type inference it gets even easier on the eyes:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/clip_image004_2.jpg\"><img decoding=\"async\" style=\"border-right: 0px;border-top: 0px;margin: 0px 0px 0px 55px;border-left: 0px;border-bottom: 0px\" height=\"61\" alt=\"clip_image004\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/11\/clip_image004_thumb.jpg\" width=\"315\" border=\"0\" \/><\/a><\/p>\n<p>I&#8217;m a fan of any feature that improves readability. <\/p>\n<h5><b>3) <\/b><b>Object Initializers<\/b><\/h5>\n<p>Generally, in the .NET frameworks, we try to design APIs that use the <a href=\"http:\/\/www.cs.cmu.edu\/~NatProg\/papers\/Stylos2007CreateSetCall.pdf\">create-set-call pattern<\/a> as our usability studies have indicated they are the easiest to use by the average programmer. Nevertheless, objects that don&#8217;t have a parameterless constructor exist in the .NET framework. When that happens, it&#8217;s really nice to be able to leverage Object Initializers which are kind of like a Dim and a With statement combined into an expression. That makes parameterized constructors somewhat easier to tolerate:<\/p>\n<pre class=\"code\">        <span>Dim<\/span> strm <span>As<\/span> <span>New<\/span> StreamWriter( _\n                      <span>New<\/span> FileStream(<span>&quot;C:out.txt&quot;<\/span>, FileMode.OpenOrCreate) _\n                        <span>With<\/span> {.Position = 10})<\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<p>It also makes creating arrays of objects much easier. <\/p>\n<pre class=\"code\">        <span>Dim<\/span> Capitals() <span>As<\/span> City = {<span>New<\/span> City <span>With<\/span> {.Name = <span>&quot;Antanarivo&quot;<\/span>, .Country = <span>&quot;Madagascar&quot;<\/span>}, _\n          <span>New<\/span> City <span>With<\/span> {.Name = <span>&quot;Belmopan&quot;<\/span>, .Country = <span>&quot;Belize&quot;<\/span>}, _\n          <span>New<\/span> City <span>With<\/span> {.Name = <span>&quot;Monaco&quot;<\/span>, .Country = <span>&quot;Monaco&quot;<\/span>}, _\n          <span>New<\/span> City <span>With<\/span> {.Country = <span>&quot;Palau&quot;<\/span>, .Name = <span>&quot;Koror&quot;<\/span>}}<\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<p><b><\/b><\/p>\n<h5><b>4) <\/b><b>Nullable <\/b><\/h5>\n<p>Nullable is the feature you&#8217;ll notice but rarely have to think about. It&#8217;s basically the .NET representation for a Nullable <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/y23b5415(vs.71).aspx\">value type<\/a> (Integer, Date, etc.) Using the designer for LINQ to SQL, the Object-Relational Mapping layer introduced in Visual Studio 2008, nullable columns in your database are mapped to this type. The result is that you can write the following expression in VB and the <i>right thing happens &#8211; <\/i>null valued rows propagate null. In the example below, the Independence property on the Country type is a nullable date, denoted as <span>Date<\/span>?<\/p>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<pre class=\"code\">        <span>Dim<\/span> virginIslands <span>As<\/span> <span>New<\/span> Country <span>With<\/span> {.Independence = <span>Nothing<\/span>}\n        <span>Dim<\/span> palau <span>As<\/span> <span>New<\/span> Country <span>With<\/span> {.Independence = #10\/1\/1994#}\n        <span>Dim<\/span> vILength = #8\/24\/2005# - virginIslands.Independence <span>' Nothing\n<\/span>        <span>Dim<\/span> pLength = #8\/24\/2005# - palau.Independence <span>' 3980.00:00:00<\/span><\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<p><b><\/b><\/p>\n<h5><b>5) <\/b><b>LINQ to DataSet <\/b><\/h5>\n<p>I love this feature because it means never having to say you&#8217;re sorry&#8230; No, really, it means that you don&#8217;t need to migrate to a new data access technology to reap the benefits of LINQ. I fill my DataSet just as before, and then I can query against the DataSet:<\/p>\n<pre class=\"code\">        <span>Me<\/span>.EmployeesTableAdapter.Fill(<span>Me<\/span>.NORTHWNDDataSet.Employees)\n        <span>Dim<\/span> query = <span>From<\/span> emp <span>In<\/span> <span>Me<\/span>.NORTHWNDDataSet.Employees _\n                    <span>Where<\/span> emp.Country = <span>&quot;USA&quot;<\/span> _\n                    <span>Order<\/span> <span>By<\/span> emp.HireDate _\n                    <span>Select<\/span> emp\n        <span>Me<\/span>.EmployeesBindingSource.DataSource = query<\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<p><b><\/b><\/p>\n<h5><b>6) <\/b><b>Syntax Tooltips<\/b><\/h5>\n<p>How cool is this?<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/clip_image006_2.jpg\"><img decoding=\"async\" style=\"border-right: 0px;border-top: 0px;border-left: 0px;border-bottom: 0px\" height=\"200\" alt=\"clip_image006\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/11\/clip_image006_thumb.jpg\" width=\"382\" border=\"0\" \/><\/a><\/p>\n<p>How about this?<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/clip_image008_2.jpg\"><img decoding=\"async\" style=\"border-right: 0px;border-top: 0px;border-left: 0px;border-bottom: 0px\" height=\"100\" alt=\"clip_image008\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/11\/clip_image008_thumb.jpg\" width=\"319\" border=\"0\" \/><\/a><\/p>\n<p>What do you think of this?<\/p>\n<p><b><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/clip_image010_2.jpg\"><img decoding=\"async\" style=\"border-right: 0px;border-top: 0px;border-left: 0px;border-bottom: 0px\" height=\"82\" alt=\"clip_image010\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/11\/clip_image010_thumb.jpg\" width=\"450\" border=\"0\" \/><\/a><\/b><b><\/b><\/p>\n<p><b><\/b><\/p>\n<h5><b>7) <\/b><b>XML Namespace support in Intellisense<\/b><\/h5>\n<p>We&#8217;ve <a href=\"http:\/\/blogs.msdn.com\/vbteam\/archive\/2007\/06\/06\/visual-basic-xml-transform-teched-demo-prep.aspx\">blogged<\/a> about <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/bb531325(VS.90).aspx\">XML Intellisense<\/a> before. But there&#8217;s a tidbit we&#8217;ve overlooked. <\/p>\n<p>When namespaces are used in the XML document you&#8217;re reading from, the Intellisense engine matches the namespace prefix and the local name. This little productivity boost can yield a significant savings in keystrokes. Instead of typing the prefix then the colon and then the local name, you just type a little bit of the local name and hit enter. Here is a small example of how it works, starting with an input document and the applicable intellisense:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/clip_image012_2.jpg\"><img decoding=\"async\" style=\"border-right: 0px;border-top: 0px;border-left: 0px;border-bottom: 0px\" height=\"259\" alt=\"clip_image012\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/11\/clip_image012_thumb.jpg\" width=\"534\" border=\"0\" \/><\/a><\/p>\n<p>If we just type the letter &#8220;t&#8221; the &#8220;tomato&#8221; entry will be selected:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/clip_image014_2.jpg\"><img decoding=\"async\" style=\"border-right: 0px;border-top: 0px;border-left: 0px;border-bottom: 0px\" height=\"61\" alt=\"clip_image014\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/11\/clip_image014_thumb.jpg\" width=\"363\" border=\"0\" \/><\/a><\/p>\n<p>If we type the letter &#8220;e&#8221; the &#8220;exa:eggplant&#8221; will be selected and the completion list will <i>also<\/i> contain the prefix &#8220;exa&#8221; and the &#8220;elephant&#8221; entry:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/clip_image016_2.jpg\"><img decoding=\"async\" style=\"border-right: 0px;border-top: 0px;border-left: 0px;border-bottom: 0px\" height=\"96\" alt=\"clip_image016\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/11\/clip_image016_thumb.jpg\" width=\"373\" border=\"0\" \/><\/a><\/p>\n<p> The next character that will be typed will determine which single entry will get selected. Now, how easy was that?<\/p>\n<h5><\/h5>\n<h5><b>8) <\/b><b>GoTo Type Definition<\/b><\/h5>\n<p>Often, when you define a variable, you want to view the type definition in code or in the Object Browser. There&#8217;s a new option in the context menu which allows you to go directly to the type definition instead of just the variable declaration. This is great when combined with type inference as it allows you confirm that the type of the variable is actually what you believe it to be. <\/p>\n<p><b><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/clip_image018_2.jpg\"><img decoding=\"async\" style=\"border-right: 0px;border-top: 0px;border-left: 0px;border-bottom: 0px\" height=\"172\" alt=\"clip_image018\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/11\/clip_image018_thumb.jpg\" width=\"381\" border=\"0\" \/><\/a><\/b> <b><\/b><\/p>\n<p><b><\/b><\/p>\n<h5><b>9) <\/b><b>Type inference for loop variables<\/b><\/h5>\n<p>Check out the following code:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/clip_image020_2.jpg\"><img decoding=\"async\" style=\"border-right: 0px;border-top: 0px;border-left: 0px;border-bottom: 0px\" height=\"112\" alt=\"clip_image020\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/11\/clip_image020_thumb.jpg\" width=\"482\" border=\"0\" \/><\/a><\/p>\n<p>And this code:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/clip_image022_2.jpg\"><img decoding=\"async\" style=\"border-right: 0px;border-top: 0px;border-left: 0px;border-bottom: 0px\" height=\"117\" alt=\"clip_image022\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/11\/clip_image022_thumb.jpg\" width=\"346\" border=\"0\" \/><\/a><\/p>\n<p>Without having to specify the type of the control variable, it&#8217;s inferred from right-hand-side expression or the collection we&#8217;re iterating over. <\/p>\n<h5><b>10) <\/b><b>Performance improvements and&#8230; Non-blocking operations!<\/b><\/h5>\n<p>The background compiler is an <i>awesome<\/i> feature that gives you immediate feedback on the correctness of the code you write. We&#8217;ve made some <i><a href=\"https:\/\/channel9.msdn.com\/ShowPost.aspx?PostID=328382#328382\">tremendous<\/a><\/i> strides in the performance of the background compiler in this release. We believe that the background compiler is 3 times faster uses 3 times less memory. Anyone who has migrated their project to 2008 should notice an improvement after a couple minutes of use.<\/p>\n<p>While we&#8217;ve made huge improvements on the throughput, certain operations like changing the declaration of a base class that&#8217;s used many times in a large project is computationally expensive. If you attempted to invoke a feature that relied on compiled information before the background compiler has a chance to do its magic, like Intellisense or the Drop Downs, previous versions of Visual Studio would grind to a halt until the compilation was complete. Those operations are no-longer blocking. So, while you might occasionally get the drop downs to look like this:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/clip_image024_2.jpg\"><img decoding=\"async\" style=\"border-right: 0px;border-top: 0px;border-left: 0px;border-bottom: 0px\" height=\"45\" alt=\"clip_image024\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/11\/clip_image024_thumb.jpg\" width=\"268\" border=\"0\" \/><\/a><\/p>\n<p>The IDE will still be responsive. <b><\/b><\/p>\n<p>Now do you have to <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/vstudio\/products\/aa700831.aspx\">download it<\/a>? Remember, you can always grab the <a href=\"http:\/\/www.microsoft.com\/express\/\">Express<\/a> Edition!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Yesterday I promised to post about the hidden gems in Visual Basic and Visual Studio 2008 that you haven&#8217;t read about in blog posts or seen at conferences. I forgot that I mentioned a few of my favorite features in the Beta1 announcement where I showed off the improvements in the Intellisense experience &#8211; statement [&hellip;]<\/p>\n","protected":false},"author":260,"featured_media":8818,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[21,195],"tags":[28,67,74,77,94,117,164,166],"class_list":["post-5163","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-im-a-vb","category-visual-basic","tag-amanda-silver","tag-extension_methods","tag-ide","tag-iqueryable","tag-linqvb9","tag-orcas","tag-vb_express","tag-vb2008"],"acf":[],"blog_post_summary":"<p>Yesterday I promised to post about the hidden gems in Visual Basic and Visual Studio 2008 that you haven&#8217;t read about in blog posts or seen at conferences. I forgot that I mentioned a few of my favorite features in the Beta1 announcement where I showed off the improvements in the Intellisense experience &#8211; statement [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/5163","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/users\/260"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/comments?post=5163"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/5163\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media\/8818"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media?parent=5163"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/categories?post=5163"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/tags?post=5163"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}