<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>The Visual Basic Team : Scott Wisniewski</title><link>http://blogs.msdn.com/vbteam/archive/tags/Scott+Wisniewski/default.aspx</link><description>Tags: Scott Wisniewski</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Drawing Maps with Visual Basic (Scott Wisniewski)</title><link>http://blogs.msdn.com/vbteam/archive/2007/11/26/drawing-maps-with-visual-basic-scott-wisniewski.aspx</link><pubDate>Mon, 26 Nov 2007 22:35:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6533703</guid><dc:creator>VBTeam</dc:creator><slash:comments>10</slash:comments><comments>http://blogs.msdn.com/vbteam/comments/6533703.aspx</comments><wfw:commentRss>http://blogs.msdn.com/vbteam/commentrss.aspx?PostID=6533703</wfw:commentRss><description>&lt;P&gt;If you find yourself looking for something to do with your &lt;A href="http://msdn2.microsoft.com/en-us/vstudio/default.aspx" mce_href="http://msdn2.microsoft.com/en-us/vstudio/default.aspx"&gt;awesome new copy of Visual Studio 2008&lt;/A&gt;, you should check out the December 2007 edition of &lt;A href="http://msdn.microsoft.com/msdnmag/issues/07/12/default.aspx" mce_href="http://msdn.microsoft.com/msdnmag/issues/07/12/default.aspx"&gt;MSDN magazine&lt;/A&gt;. It features an article, written by me, that provides a walk through on how to visualize data on a map using VB 9, WPF and LINQ. &lt;/P&gt;
&lt;P&gt;To give you a sneak preview of what the app described in the article does, I've included a screen shot below: &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH: 800px; HEIGHT: 600px" height=600 src="http://blogs.msdn.com/photos/vbteam_gallery2/images/6533749/original.aspx" width=800 mce_src="http://blogs.msdn.com/photos/vbteam_gallery2/images/6533749/original.aspx"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Over my next several posts I plan on expanding on the article by showing how you can extend the application by adding new functionality to it. For now, I will give you some time to read through the &lt;A href="http://msdn.microsoft.com/msdnmag/issues/07/12/Maps/default.aspx" mce_href="http://msdn.microsoft.com/msdnmag/issues/07/12/Maps/default.aspx"&gt;article&lt;/A&gt;, download the &lt;A href="http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/MapsWithVB9WPF2007_12.exe" mce_href="http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/MapsWithVB9WPF2007_12.exe"&gt;code sample&lt;/A&gt;, and play around with the app. In my next post I will show how you can make the application multithreaded while still taking full advantage of WPF data binding. &lt;/P&gt;
&lt;P&gt;Enjoy!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6533703" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/vbteam/archive/tags/LINQ_2F00_VB9/default.aspx">LINQ/VB9</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/Scott+Wisniewski/default.aspx">Scott Wisniewski</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/VB2008/default.aspx">VB2008</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/XML/default.aspx">XML</category></item><item><title>A Note about Enums (Scott Wisniewski)</title><link>http://blogs.msdn.com/vbteam/archive/2007/10/15/a-note-about-enums-scott-wisniewski.aspx</link><pubDate>Tue, 16 Oct 2007 00:32:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5464425</guid><dc:creator>VBTeam</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/vbteam/comments/5464425.aspx</comments><wfw:commentRss>http://blogs.msdn.com/vbteam/commentrss.aspx?PostID=5464425</wfw:commentRss><description>&lt;P&gt;I recently received an email from a customer who had a few questions about "enum inheritance" in VB, specifically as to why it wasn't supported. In particular, he sent us the following snippet of VB code&amp;nbsp; (I've changed the names of the classes and methods involved)&amp;nbsp; : &lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff size=2&gt;&lt;/P&gt;
&lt;P&gt;Option&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Strict&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;On&lt;/P&gt;
&lt;P&gt;Public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Class&lt;/FONT&gt;&lt;FONT size=2&gt; BaseClass&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Enum&lt;/FONT&gt;&lt;FONT size=2&gt; SomeEnum&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Value1&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Value2&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;End&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Enum&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Overridable&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Sub&lt;/FONT&gt;&lt;FONT size=2&gt; DoSomething(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;ByVal&lt;/FONT&gt;&lt;FONT size=2&gt; e &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;As&lt;/FONT&gt;&lt;FONT size=2&gt; SomeEnum)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Select&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Case&lt;/FONT&gt;&lt;FONT size=2&gt; e&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 size=2&gt;Case&lt;/FONT&gt;&lt;FONT size=2&gt; SomeEnum.Value1&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; DoSomething1()&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 size=2&gt;Case&lt;/FONT&gt;&lt;FONT size=2&gt; SomeEnum.Value2&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; DoSomething2()&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 size=2&gt;End&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Select&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;End&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Sub&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Sub&lt;/FONT&gt;&lt;FONT size=2&gt; DoSomething1()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;End&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Sub&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Sub&lt;/FONT&gt;&lt;FONT size=2&gt; DoSomething2()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;End&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Sub&lt;/P&gt;
&lt;P&gt;End&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Class&lt;/P&gt;
&lt;P&gt;Public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Class&lt;/FONT&gt;&lt;FONT size=2&gt; DerivedClass&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Inherits&lt;/FONT&gt;&lt;FONT size=2&gt; BaseClass&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Shadows&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Enum&lt;/FONT&gt;&lt;FONT size=2&gt; SomeEnum&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Value1&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Value2&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Value3&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;End&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Enum&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Shadows&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Sub&lt;/FONT&gt;&lt;FONT size=2&gt; DoSomething(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;ByVal&lt;/FONT&gt;&lt;FONT size=2&gt; e &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;As&lt;/FONT&gt;&lt;FONT size=2&gt; SomeEnum)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Select&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Case&lt;/FONT&gt;&lt;FONT size=2&gt; e&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 size=2&gt;Case&lt;/FONT&gt;&lt;FONT size=2&gt; SomeEnum.Value1, SomeEnum.Value2&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&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; MyBase&lt;/FONT&gt;&lt;FONT size=2&gt;.DoSomething(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;CType&lt;/FONT&gt;&lt;FONT size=2&gt;(e, BaseClass.SomeEnum))&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 size=2&gt;Case&lt;/FONT&gt;&lt;FONT size=2&gt; SomeEnum.Value3&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; DoSomething3()&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 size=2&gt;End&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Select&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;End&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Sub&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Sub&lt;/FONT&gt;&lt;FONT size=2&gt; DoSomething3()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;End&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Sub&lt;/P&gt;
&lt;P&gt;End&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Class&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;BR&gt;&lt;BR&gt;&lt;/P&gt;
&lt;P&gt;and asked us the following questions:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Why does SomeEnum have to be marked as shadows inside DerivedClass? Why can't I use "overloads"? &lt;/LI&gt;
&lt;LI&gt;Why does DerivedClass.DoSomething() have to cast it's enum value to the value in the base class.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;I figured other people may have run into similar issues any may have some of the same questions, and so though this would make a good blog post.&lt;/P&gt;
&lt;P&gt;My response is below:&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;VB does not support "Enum" inheritance, and so it is not possible for one Enum type to inherit from another "Enum" type. &lt;/P&gt;
&lt;P&gt;This is mainly because "Enum" inheritance is not safe. In general, an inheritance relationship between two types implies that it is possible to always treat a "more specific" derived class as if it was also a "more general" base class. This relationship does not hold between two enums.&lt;/P&gt;
&lt;P&gt;This is because, enum's are really not object-oriented concepts. Instead, an enum is just a collection of constant variable declarations conveniently packaged into a type. What defines the "identity" of an enum is the set of values it may take.&lt;/P&gt;
&lt;P&gt;In general, if you were to take an enum like so:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;Enum&lt;/SPAN&gt; Foo &lt;BR&gt;    Value1 &lt;BR&gt;    Value2&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;Enum &lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;and then try to extend it with inheritance like so (this is not legal):&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;Enum&lt;/SPAN&gt; FooDerived &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;Inherits&lt;/SPAN&gt; Foo &lt;BR&gt;    Value3&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;Enum&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;It would no longer be possible to say that "any FooDerived" is also a "Foo". This is because the value "Value3" cannot be treated as if it was a "Foo" value.&lt;/P&gt;
&lt;P&gt;The compiler does, for convenience, provide conversions between different enum types. This is because in the event that you know the value your are converting can be represented in the target type then it is safe to do the conversion. Because it is not always safe, however, the conversion is treated as a "narrowing" (unsafe) conversion rather than a "widening" (safe) conversion.&lt;/P&gt;
&lt;P&gt;When "option strict" is turned on the compiler will not implicitly perform unsafe conversions. Instead it requires you to explicitly tell it when a potentially unsafe conversion is in fact safe by writing an explicit "CType".&lt;/P&gt;
&lt;P&gt;Marking the SomeEnum type DerivedClass as shadows makes it a completely new enum type from the one defined in "BaseClass". Because "BaseClass.SomeEnum" and "DerivedClass.SomeEnum" are different enum types, the conversion is not safe, and thus requires an explicit cast.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5464425" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/vbteam/archive/tags/Scott+Wisniewski/default.aspx">Scott Wisniewski</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/VB2005/default.aspx">VB2005</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/VB2008/default.aspx">VB2008</category></item><item><title>Channel9 Interview: Scott Wisniewski on Extension Methods in Visual Basic 9.0 (Beth Massi)</title><link>http://blogs.msdn.com/vbteam/archive/2007/08/03/channel9-interview-scott-wisniewski-on-extension-methods-in-visual-basic-9-0-beth-massi.aspx</link><pubDate>Fri, 03 Aug 2007 19:46:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4209007</guid><dc:creator>VBTeam</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/vbteam/comments/4209007.aspx</comments><wfw:commentRss>http://blogs.msdn.com/vbteam/commentrss.aspx?PostID=4209007</wfw:commentRss><description>&lt;P&gt;I just posted an &lt;A class="" href="http://channel9.msdn.com/ShowPost.aspx?PostID=331848" target=_blank mce_href="http://channel9.msdn.com/ShowPost.aspx?PostID=331848"&gt;interview with Scott on Channel9&lt;/A&gt; where he talks about extension methods, a new language feature&amp;nbsp;in Visual Basic 9.0:&lt;/P&gt;
&lt;P&gt;﻿In this in interview &lt;A class="" href="http://blogs.msdn.com/vbteam/archive/tags/Scott+Wisniewski/default.aspx" target=_blank mce_href="http://blogs.msdn.com/vbteam/archive/tags/Scott+Wisniewski/default.aspx"&gt;Scott Wisniewski&lt;/A&gt;, a Developer on the Visual Basic Team, talks about Extension Methods and shows us a couple interesting LINQ providers. In his own unique way, Scott dives into the meaning of Extension Methods and how they can extend types with discoverable methods which are part of the underpinnings of LINQ. He walks through some code written as an extension to LINQ query results to generate pie charts and then dives into a LINQ provider he built that hooks into Performance Monitor to give you real-time statistics on your LINQ queries. You can also read &lt;A class="" href="http://msdn.microsoft.com/msdnmag/issues/07/08/BasicInstincts/" target=_blank mce_href="http://msdn.microsoft.com/msdnmag/issues/07/08/BasicInstincts/"&gt;Scott's MSDN Magazine article here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Enjoy!&lt;/P&gt;
&lt;P&gt;-&lt;A class="" href="http://blogs.msdn.com/bethmassi/" mce_href="http://blogs.msdn.com/bethmassi/"&gt;Beth Massi&lt;/A&gt;, VS Community&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4209007" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/vbteam/archive/tags/LINQ_2F00_VB9/default.aspx">LINQ/VB9</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/Scott+Wisniewski/default.aspx">Scott Wisniewski</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/Beth+Massi/default.aspx">Beth Massi</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/VB2008/default.aspx">VB2008</category></item><item><title>Lambdas, and Take While, and Group By, Oh My!</title><link>http://blogs.msdn.com/vbteam/archive/2007/07/26/lambdas-and-take-while-and-group-by-oh-my.aspx</link><pubDate>Thu, 26 Jul 2007 20:02:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4068272</guid><dc:creator>VBTeam</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/vbteam/comments/4068272.aspx</comments><wfw:commentRss>http://blogs.msdn.com/vbteam/commentrss.aspx?PostID=4068272</wfw:commentRss><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;Hooray! &lt;/FONT&gt;&lt;A href="http://msdn2.microsoft.com/en-us/vstudio/" mce_href="http://msdn2.microsoft.com/en-us/vstudio/"&gt;&lt;FONT face=Calibri size=3&gt;Visual Basic 2008 Beta2&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Calibri size=3&gt; has been released to the wild today to return to its natural habitat – the desktops of our beloved customers. (Please note our smiling GPM's face on that landing page -- he's &lt;STRONG&gt;so &lt;/STRONG&gt;happy the Beta is done.)&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;What’s inside? So much that there might be &lt;I style="mso-bidi-font-style: normal"&gt;more&lt;/I&gt; new features than we released in Beta1, but who’s counting? Here’s a laundry list that’s specific to the VB language that’s &lt;I style="mso-bidi-font-style: normal"&gt;new &lt;/I&gt;for Beta2:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpFirst style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo1"&gt;&lt;SPAN style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;Query operators&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l0 level2 lfo1; mso-add-space: auto"&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Courier New'"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT size=3&gt;o&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;Group By, Group Join, Join, Take [While], Skip [While], Aggregate, Count, Sum, Min, Max, Average, From &lt;/FONT&gt;&lt;SPAN style="FONT-FAMILY: Wingdings; mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-char-type: symbol; mso-symbol-font-family: Wingdings"&gt;&lt;SPAN style="mso-char-type: symbol; mso-symbol-font-family: Wingdings"&gt;à&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri&gt; Let&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo1"&gt;&lt;SPAN style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;Nullable support&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo1"&gt;&lt;SPAN style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;Lambda Expressions (aka Inline Functions)&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo1"&gt;&lt;SPAN style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;Partial Methods – &lt;/FONT&gt;&lt;A href="http://weblogs.asp.net/scottgu/archive/2007/07/16/linq-to-sql-part-5-binding-ui-using-the-asp-linqdatasource-control.aspx" mce_href="http://weblogs.asp.net/scottgu/archive/2007/07/16/linq-to-sql-part-5-binding-ui-using-the-asp-linqdatasource-control.aspx"&gt;&lt;FONT face=Calibri size=3&gt;ScottGu&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Calibri size=3&gt; mentioned this the other day &amp;amp; &lt;/FONT&gt;&lt;A href="http://blogs.msdn.com/vbteam/archive/2007/03/27/partial-methods.aspx" mce_href="http://blogs.msdn.com/vbteam/archive/2007/03/27/partial-methods.aspx"&gt;&lt;FONT face=Calibri size=3&gt;ScottWis&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Calibri size=3&gt; posted a couple weeks back&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpLast style="MARGIN: 0in 0in 10pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo1"&gt;&lt;SPAN style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;Anonymous Types w/Keys – Which &lt;/FONT&gt;&lt;A href="http://www.panopticoncentral.net/archive/2007/05/11/20566.aspx" mce_href="http://www.panopticoncentral.net/archive/2007/05/11/20566.aspx"&gt;&lt;FONT face=Calibri size=3&gt;PaulV&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Calibri size=3&gt; has already discussed&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;Here are a bunch of queries you can now write with VB!&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid; mso-element: para-border-div; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242"&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; LINE-HEIGHT: 115%; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;' Find suppliers in the same city as customers&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 115%; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;From&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; cust &lt;SPAN style="COLOR: blue"&gt;In&lt;/SPAN&gt; db.Customers _&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;Join&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; sup &lt;SPAN style="COLOR: blue"&gt;In&lt;/SPAN&gt; db.Suppliers _&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;On&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; cust.City &lt;SPAN style="COLOR: blue"&gt;Equals&lt;/SPAN&gt; sup.City _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 115%; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;Select&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; cust.CompanyName, sup.ContactName, cust.City&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; LINE-HEIGHT: 115%; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;' Find suppliers in the same city, with the same postalcode as customers&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;From&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; cust &lt;SPAN style="COLOR: blue"&gt;In&lt;/SPAN&gt; db.Customers _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;Join&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; sup &lt;SPAN style="COLOR: blue"&gt;In&lt;/SPAN&gt; db.Suppliers _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;On&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; cust.City &lt;SPAN style="COLOR: blue"&gt;Equals&lt;/SPAN&gt; sup.City &lt;SPAN style="COLOR: blue"&gt;And&lt;/SPAN&gt; cust.PostalCode &lt;SPAN style="COLOR: blue"&gt;Equals&lt;/SPAN&gt; sup.PostalCode&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 10pt; BORDER-LEFT: medium none; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 115%; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;Select&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; cust.CompanyName, sup.ContactName, cust.City&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;' Find the average unit price and count for products by category&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;From&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; prod &lt;SPAN style="COLOR: blue"&gt;In&lt;/SPAN&gt; db.Products _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;Group&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; &lt;SPAN style="COLOR: blue"&gt;By&lt;/SPAN&gt; prod.CategoryID _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;Into&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; Average(prod.UnitPrice), Count()&lt;SPAN style="COLOR: green"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;' For each customer find the group of the suppliers in the same country&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;From&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; cust &lt;SPAN style="COLOR: blue"&gt;In&lt;/SPAN&gt; db.Customers _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;Group&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; &lt;SPAN style="COLOR: blue"&gt;Join&lt;/SPAN&gt; sup &lt;SPAN style="COLOR: blue"&gt;In&lt;/SPAN&gt; db.Suppliers _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;On&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; cust.Country &lt;SPAN style="COLOR: blue"&gt;Equals&lt;/SPAN&gt; sup.Country _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;Into&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; SuppliersInCountry = &lt;SPAN style="COLOR: blue"&gt;Group&lt;/SPAN&gt; _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 10pt; BORDER-LEFT: medium none; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 115%; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;Select&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; cust.CompanyName, SuppliersInCountry&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;' For each customer, the count of the number of suppliers in the same country&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;From&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; cust &lt;SPAN style="COLOR: blue"&gt;In&lt;/SPAN&gt; db.Customers _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;Group&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; &lt;SPAN style="COLOR: blue"&gt;Join&lt;/SPAN&gt; sup &lt;SPAN style="COLOR: blue"&gt;In&lt;/SPAN&gt; db.Suppliers _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;On&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; cust.Country &lt;SPAN style="COLOR: blue"&gt;Equals&lt;/SPAN&gt; sup.Country _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;Into&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; NumSuppliers = Count() _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;Select&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; cust.CompanyName, NumSuppliers&lt;SPAN style="COLOR: green"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;' Avg price, avg # in stock, and max on order for non-discontinued products&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;Aggregate&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; prod &lt;SPAN style="COLOR: blue"&gt;In&lt;/SPAN&gt; db.Products _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;Where&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; &lt;SPAN style="COLOR: blue"&gt;Not&lt;/SPAN&gt; prod.Discontinued _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;Into&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; AvgPrice = Average(prod.UnitPrice), _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;AvgInStock = Average(prod.UnitsInStock), _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 10pt; BORDER-LEFT: medium none; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;MaxOnOrder = Max(prod.UnitsOnOrder)&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;' Find orderID, OrderDate, and OrderTotal for each order&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;From&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; order &lt;SPAN style="COLOR: blue"&gt;In&lt;/SPAN&gt; db.Orders _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;Where&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; order.OrderDate &amp;gt; #7/22/1996# _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;Aggregate&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; ordDet &lt;SPAN style="COLOR: blue"&gt;In&lt;/SPAN&gt; order.Order_Details _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;Into&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; OrderTotal = _&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Sum(ordDet.UnitPrice *ordDet.Quantity * (1 - ordDet.Discount))&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;Select&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; order.OrderID, order.OrderDate, OrderTotal&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;' Fill a dictionary with the customers by CompanyName&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; BACKGROUND: #f2f2f2; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 0pt; BORDER-LEFT: medium none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: solid windowtext .5pt; mso-background-themecolor: background1; mso-background-themeshade: 242; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;db.Customers.ToDictionary(&lt;SPAN style="COLOR: blue"&gt;Function&lt;/SPAN&gt;(cust &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; Customer) cust.CompanyName)&lt;SPAN style="COLOR: green"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/DIV&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;In addition to all the new language support, we now have keyword Intellisense (finally!)&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt" mce_keep="true"&gt;&lt;IMG title="Keyword Intellisense" style="WIDTH: 713px; HEIGHT: 344px" height=344 alt="Keyword Intellisense" src="http://blogs.msdn.com/photos/vbteam/images/4068260/original.aspx" width=713 mce_src="http://blogs.msdn.com/photos/vbteam/images/4068260/original.aspx"&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;We have &lt;A class="" title="XML Intellisense" href="http://blogs.msdn.com/vbteam/archive/2007/06/06/visual-basic-xml-transform-teched-demo-prep.aspx" mce_href="http://blogs.msdn.com/vbteam/archive/2007/06/06/visual-basic-xml-transform-teched-demo-prep.aspx"&gt;XML Intellisense&lt;/A&gt;! What?? That’s right.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;IMG title="XML Intellisense" style="WIDTH: 476px; HEIGHT: 229px" height=229 alt="XML Intellisense" src="http://blogs.msdn.com/photos/vbteam/images/3119902/original.aspx" width=476 mce_src="http://blogs.msdn.com/photos/vbteam/images/3119902/original.aspx"&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;And we’ve done some major performance improvements for the background compiler – let us know if you experience any sluggishness&amp;nbsp;for this&amp;nbsp;Beta.&amp;nbsp;&amp;nbsp;(BTW, you should check out &lt;A class="" title="Installation Notes for Beta2" href="http://weblogs.asp.net/scottgu/archive/2007/07/26/vs-2008-and-net-3-5-beta-2-released.aspx" mce_href="http://weblogs.asp.net/scottgu/archive/2007/07/26/vs-2008-and-net-3-5-beta-2-released.aspx"&gt;Scott's post&lt;/A&gt; on Beta2 to avoid some problems with AJAX extensions if you're installing to a machine that has had previous versions of Orcas installed on it or has VS 2005 side by side.) &lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND: white; MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none; mso-background-themecolor: background1"&gt;&lt;FONT face=Calibri size=3&gt;Also, don’t forget to look for other exciting features around the product that pertain to VB and/or LINQ. For example, Linq to SQL now supports the &lt;/FONT&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;Like&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt; operator! There’s also a new &lt;/FONT&gt;&lt;A href="http://weblogs.asp.net/scottgu/archive/2007/07/16/linq-to-sql-part-5-binding-ui-using-the-asp-linqdatasource-control.aspx" mce_href="http://weblogs.asp.net/scottgu/archive/2007/07/16/linq-to-sql-part-5-binding-ui-using-the-asp-linqdatasource-control.aspx"&gt;&lt;FONT face=Calibri size=3&gt;ASP:LinqDataSource&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Calibri size=3&gt; control. &lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND: white; MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none; mso-background-themecolor: background1"&gt;&lt;FONT face=Calibri size=3&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND: white; MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none; mso-background-themecolor: background1"&gt;&lt;FONT face=Calibri size=3&gt;So, &lt;/FONT&gt;&lt;A href="http://msdn2.microsoft.com/en-us/vstudio/" mce_href="http://msdn2.microsoft.com/en-us/vstudio/"&gt;&lt;FONT face=Calibri size=3&gt;get the bits&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Calibri size=3&gt; while they’re hot!&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND: white; MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none; mso-background-themecolor: background1"&gt;&lt;FONT face=Calibri size=3&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND: white; MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none; mso-background-themecolor: background1"&gt;&lt;FONT face=Calibri size=3&gt;-Amanda&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4068272" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/vbteam/archive/tags/Amanda+Silver/default.aspx">Amanda Silver</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/Paul+Vick/default.aspx">Paul Vick</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/LINQ_2F00_VB9/default.aspx">LINQ/VB9</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/IDE/default.aspx">IDE</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/Scott+Wisniewski/default.aspx">Scott Wisniewski</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/VB2008/default.aspx">VB2008</category></item><item><title>Shameless Plug (Scott Wisniewski)</title><link>http://blogs.msdn.com/vbteam/archive/2007/07/12/shameless-plug-scott-wisniewski.aspx</link><pubDate>Fri, 13 Jul 2007 02:47:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:3838460</guid><dc:creator>VBTeam</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/vbteam/comments/3838460.aspx</comments><wfw:commentRss>http://blogs.msdn.com/vbteam/commentrss.aspx?PostID=3838460</wfw:commentRss><description>&lt;P&gt;If you get a chance, you should check out the August 2007 edition of MSDN Magazine. In addition to its usual array of awesome goodies, this month's edition features a super cool Basic Instincts column, written by me. In it I discuss the design of Query Comprehensions in VB, giving an overview of the basic framework used by the compiler to translate queries into code. &lt;/P&gt;
&lt;P&gt;I hope that it should be interesting to anyone who wants to write their own custom query provider, or for anyone who just wants an understanding of how things work under the covers. &lt;/P&gt;
&lt;P&gt;If you don't have access to the print version, you can see the online copy here: &lt;/P&gt;
&lt;P&gt;&lt;A href="http://msdn.microsoft.com/msdnmag/issues/07/08/BasicInstincts/" mce_href="http://msdn.microsoft.com/msdnmag/issues/07/08/BasicInstincts/"&gt;http://msdn.microsoft.com/msdnmag/issues/07/08/BasicInstincts/&lt;/A&gt;. &lt;/P&gt;
&lt;P&gt;Enjoy! &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3838460" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/vbteam/archive/tags/LINQ_2F00_VB9/default.aspx">LINQ/VB9</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/Scott+Wisniewski/default.aspx">Scott Wisniewski</category></item><item><title>What is the difference between VB 9, VBx and Silverlight? (Scott Wisniewski)</title><link>http://blogs.msdn.com/vbteam/archive/2007/06/07/what-is-the-difference-between-vb-9-vbx-and-silverlight.aspx</link><pubDate>Fri, 08 Jun 2007 04:58:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:3152912</guid><dc:creator>VBTeam</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/vbteam/comments/3152912.aspx</comments><wfw:commentRss>http://blogs.msdn.com/vbteam/commentrss.aspx?PostID=3152912</wfw:commentRss><description>&lt;P&gt;I recently received an email from a customer asking for clarification as to what the difference was between &lt;A href="http://msdn2.microsoft.com/en-us/library/ms364068(VS.80).aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms364068(VS.80).aspx"&gt;VB 9&lt;/A&gt;, &lt;A href="http://www.panopticoncentral.net/archive/2007/05/01/20383.aspx" mce_href="http://www.panopticoncentral.net/archive/2007/05/01/20383.aspx"&gt;VBx&lt;/A&gt; and &lt;A href="http://silverlight.net/" mce_href="http://silverlight.net/"&gt;Sliverlight&lt;/A&gt;. In particular, it seems as if we have been releasing so much information about cool new stuff that at least a few people have become confused, making them a bit nervous about the future of VB. &lt;/P&gt;
&lt;P&gt;The customer had also expressed some concerns about upgrading from VS 2005 to Orcas (VS 2008), particularly because he was considering making an upgrade from VB 6 to VS 2005 and wanted to make sure he would be able to take advantage of &lt;A href="http://msdn2.microsoft.com/en-us/vstudio/aa700830.aspx" mce_href="http://msdn2.microsoft.com/en-us/vstudio/aa700830.aspx"&gt;Orcas&lt;/A&gt; when it was released. &lt;/P&gt;
&lt;P&gt;I figured there may be other customers that have similar concerns, and so thought this would make a good blog post, particularly because it's been a while since I've posted anything (&lt;SPAN style="FONT-FAMILY: Wingdings"&gt;J&lt;/SPAN&gt;). &lt;/P&gt;
&lt;P&gt;As a result I've included a few of the questions he asked (paraphrased) below, along with my answers. &lt;/P&gt;
&lt;P&gt;I hope this helps.&lt;BR&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;What is the difference between VB 9 and VBx? Which one is the next version of Visual Studio?&lt;/STRONG&gt;&lt;BR&gt;&lt;BR&gt;Visual Basic 9 is the next version of Visual Basic. Visual Basic 10, or VBx as it's sometimes called, is the version of Visual Basic that will follow VB 9. Currently VBx is in very early stages, and is a long way off from production. In fact, most of our development team is actively working on VB 9. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Why on earth would you start talking about VB 10 before you've even released VB 9? This is confusing. &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The product cycle for VB 9 is starting to wind down. We recently released Beta 1 of Visual Studio Code Name "Orcas", and are currently working on releasing Beta 2. As the product cycle starts to wind down, our language design team is starting to think about what the "next next" version of the product will look like. They do this mainly as a way to "keep the pipeline moving". If they had to wait until VB 9 was 100% complete before they started thinking about VB 10, then there would end up being a significant delay from when we finished VB 9 until we could start working on VB 10. This is because designing a product, and coming up with a plan to develop it can be extremely time consuming. It requires us to come up with a design, create a schedule, make any necessary organizational changes, and ensure we have the right staffing levels, all before we start coding. By "overlapping" the early design work for VB 10 with the "end game" work for VB 9 we are able to better "bootstrap" the whole process, thus making the transition from one project to the next as smooth as possible. &lt;/P&gt;
&lt;P&gt;As our design team comes up with designs they like to release information about them as early as possible. The earlier we can get information out to our customers, the earlier we can get feedback about the things we are doing. This helps us to build the products that actually meet our customers' needs. One thing we've managed to learn over the years is that the best possible way we can learn what it is that our customers want is to engage with them early and often. &lt;/P&gt;
&lt;P&gt;As a result, near the end of a product cycle we will release information about our plans for the version of the product to follow the one we are currently working on. This gives our customers the chance to comment on it and let us know what they think. We then take that feedback and use it to develop a more complete plan for what we want to do. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;What is VB 10 going to be like? What is this Silverlight Thing I keep hearing about? Is Silverlight a replacement for Visual Studio? &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Our plans for VBx and Silverlight are still very rough and are nowhere near complete. As our customers start to use VB 9 and provide us with feedback that data will drive exactly what we end up doing in VB 10. That being said, however, we do have some rough ideas of the things we would like to do. &lt;/P&gt;
&lt;P&gt;Silverlight 1.1 is a new light weight version of the .NET Framework that will allow you to develop rich applications that run in a web browser using .NET languages. The basic idea is to allow you to replace client side java script with .NET enabled languages, allowing you to write both the client side and sever side portions of your web applications in the same language. It also allows you to use WPF (windows presentation foundation) and WCF (windows communication foundation) to create extremely rich and interactive web applications in a way that is much easier than what is possible using HTML, Ajax, Java Script, or Flash. &lt;/P&gt;
&lt;P&gt;VB 10 is going to be the version of Visual Basic that will follow VB 9 (the "next next version"). It will include new features designed to make VB a really great language for developing SilverLight apps, as well as enhancements to many of the new feature we are delivering in VB 9, such as Linq. You should still be able to do all the things with VB 10 that you could do with both VB 9 and VB 8. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;The migration from VB 6 to VS 2005 is non-trivial. If I upgrade to VS 2005 will I able to use VB 9 when it comes out, or will I have to scrap all my work? What about VB 10? Should I be worried about the future of VB?&lt;/STRONG&gt; &lt;/P&gt;
&lt;P&gt;The transition from VB 8.0 to VB 9.0 should be smooth and relatively painless. We have gone to great lengths to ensure this. &lt;/P&gt;
&lt;P&gt;Our plan is to also make the migration from VB 9 to VB 10 equally painless. &lt;/P&gt;
&lt;P&gt;Although the migration from VB 6 to VB.NET is a bit tough, we are actively working on making that easier as well. We have been releasing a "VB Interoperability Toolkit" that allows an application to be gradually migrated from VB 6 to VS 2005, rather than requiring the whole thing to be migrated at once. &lt;/P&gt;
&lt;P&gt;You can get more information about it here: &lt;/P&gt;
&lt;P&gt;&lt;A href="http://msdn2.microsoft.com/en-us/vbasic/aa701257.aspx" mce_href="http://msdn2.microsoft.com/en-us/vbasic/aa701257.aspx"&gt;http://msdn2.microsoft.com/en-us/vbasic/aa701257.aspx&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;As far as the future of VB, you should definitely not be worried. &lt;/P&gt;
&lt;P&gt;Microsoft is committed to VB, and making it a great language for developing applications for our various platforms. The future of VB should be a bright one!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3152912" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/vbteam/archive/tags/LINQ_2F00_VB9/default.aspx">LINQ/VB9</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/Scott+Wisniewski/default.aspx">Scott Wisniewski</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/VB2005/default.aspx">VB2005</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/DLR/default.aspx">DLR</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/Web/default.aspx">Web</category></item><item><title>Partial Methods</title><link>http://blogs.msdn.com/vbteam/archive/2007/03/27/partial-methods.aspx</link><pubDate>Wed, 28 Mar 2007 07:03:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1971409</guid><dc:creator>VBTeam</dc:creator><slash:comments>17</slash:comments><comments>http://blogs.msdn.com/vbteam/comments/1971409.aspx</comments><wfw:commentRss>http://blogs.msdn.com/vbteam/commentrss.aspx?PostID=1971409</wfw:commentRss><description>&lt;P&gt;About two weeks ago I had the opportunity to attend the product group dinner associated with the &lt;A href="https://mvp.support.microsoft.com/mvpsummit" mce_href="https://mvp.support.microsoft.com/mvpsummit"&gt;Global MVP Summit&lt;/A&gt; that was behind held here at Microsoft. Besides a free meal, this also gave me the excellent opportunity to meet with some of our &lt;A href="http://mvp.support.microsoft.com/mvpexecsum" mce_href="http://mvp.support.microsoft.com/mvpexecsum"&gt;MVPs&lt;/A&gt; and discuss their impressions with Visual Studio and all the cool new features we are introducing for Orcas. At the dinner, I had an opportunity to talk with a group of VB MVPS from Japan, who met with me and about 5 or 6 other members of the VB team. While we were talking, a couple of them asked me a few questions about partial methods. Unfortunately, I do not speak Japanese, and so had some trouble answering them. Figuring that written English may be easier to understand than my idiomatic spoken English, I decided to make Partial Methods the topic of my next blog post. &lt;/P&gt;
&lt;P&gt;As a result, I've included their questions below along with my answers. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;What are Partial Methods?&lt;/STRONG&gt; &lt;/P&gt;
&lt;P&gt;In a nut-shell, partial methods are a light-weight replacement for events designed primarily for use by automatic code generators. They are declared by creating a private method with an empty body and decorating it with the &lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Courier New"&gt;Partial&lt;/SPAN&gt; keyword. The method may then be "re-implemented" elsewhere within its containing class. If the method is implemented, then the compiler will redirect all calls to the partial method to the implementing method. If the method is not implemented in its containing class, then the compiler silently removes any calls to it from the program. They differ from events in several ways, mainly: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;A partial method can only have 1 "implementing method", where events may have any number of handlers &lt;/LI&gt;
&lt;LI&gt;The implementing method for a partial method must be in the same class as the partial method its self, where as event handlers can pretty much be defined in any type that has access to the event instance &lt;/LI&gt;
&lt;LI&gt;An event will throw if it has no handlers and is invoked. Usually this requires comparing the event against &lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Courier New"&gt;Nothing&lt;/SPAN&gt; to safe guard against an exception. On the other hand, if a partial method does not have an implementing method then the compiler will simply optimize away any calls to it. &lt;/LI&gt;
&lt;LI&gt;The wiring of events is dynamic, which means that handlers can be added and removed from an event at runtime. This can either be done implicitly, using &lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Courier New"&gt;WithEvents&lt;/SPAN&gt; variables and &lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Courier New"&gt;Handles&lt;/SPAN&gt; clauses or explicitly using &lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Courier New"&gt;AddHandler&lt;/SPAN&gt; and &lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Courier New"&gt;RemoveHandler&lt;/SPAN&gt; statements. The wiring of partial methods, however, is always done at compile time, and an implementing method is associated with its declaring method by simply writing a method with the same name and signature as the partial method. Once this is done, all references to the partial method are rewritten by the compiler to refer to its implementing method. &lt;/LI&gt;
&lt;LI&gt;Events may be declared with any accessibility (public, private, or friend). Partial Methods, on the other hand must be private. The method that implements it, however, may have any accessibility. &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;An example use of partial methods is shown below: &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: Courier New"&gt;'Designer File &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Partial&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Class&lt;/SPAN&gt; DesignerGeneratedClass &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Partial Private Sub&lt;/SPAN&gt; OnFoo()&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Partial&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Private Sub&lt;/SPAN&gt; OnBar() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; DoSomething() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;OnFoo() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;OnBar() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Class &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: Courier New"&gt;'Code Behind File &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Class&lt;/SPAN&gt; DesignerGeneratedClass &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Overridable&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; OnFoo() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;Console.WriteLine(&lt;SPAN style="COLOR: #a31515"&gt;"Foo Occured"&lt;/SPAN&gt;) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Class&lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Here we define a class named DesignerGeneratedClass split into two partial classes. It is designed to mimic typical code generation scenarios where one partial class contains designer generated code and another contains user generated code. For example, Windows Forms classes and pages in ASP.NET Web Application Projects utilize this approach. In the designer generated file we define a utility method, DoSomething, that calls two partial method declarations OnFoo and OnBar. The user file implements OnFoo, but not OnBar. When the VB compiler processes this class, it notices this and emits a body for DoSomething() that only calls OnFoo(). &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;What are Partial Methods useful for?&lt;BR&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;For most applications, events are almost always a better choice than partial methods due to their increased flexibility. However, there are some scenarios where they come in handy. A couple of them are listed below: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;In automatic code generators &lt;BR&gt;&lt;BR&gt;Partial methods enable code generators to write extremely flexible code by creating a lot of "hooks", where developers can provide their own custom functionality that integrates into the "boiler plate" code created by the generator. Because the hooks are optimized away if they aren't used, no performance penalty is introduced by defining them. This is really useful if generated code needs to be used in high performance scenarios. For example, partial methods are used by the DLINQ designer for exactly this purpose. Developers wishing to invoke custom code on their data objects when properties are set can do so without requiring all users of DLINQ to suffer performance problems. &lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Courier New"&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;To increase the readability of code that uses conditional compilation constants.&lt;BR&gt;&lt;BR&gt;Consider the following code that uses conditional compilation constants in VB.&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;BR&gt;Class&lt;/SPAN&gt; UglyConditonalCompilationCode&lt;BR&gt;&lt;BR&gt;#&lt;SPAN style="COLOR: blue"&gt;If&lt;/SPAN&gt; DEBUG &lt;SPAN style="COLOR: blue"&gt;Then&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; LogMessage(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; s &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;String&lt;/SPAN&gt;)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(s)&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;BR&gt;&lt;/SPAN&gt;#&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;If&lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Sub&lt;/SPAN&gt; DoStuff()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DoFirstThing()&lt;BR&gt;#&lt;SPAN style="COLOR: blue"&gt;If&lt;/SPAN&gt; DEBUG &lt;SPAN style="COLOR: blue"&gt;Then&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LogMessage(&lt;SPAN style="COLOR: #a31515"&gt;"Did first thing"&lt;/SPAN&gt;)&lt;BR&gt;#&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;If&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DoSecondThing()&lt;BR&gt;#&lt;SPAN style="COLOR: blue"&gt;If&lt;/SPAN&gt; DEBUG &lt;SPAN style="COLOR: blue"&gt;Then&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LogMessage(&lt;SPAN style="COLOR: #a31515"&gt;"Did second thing"&lt;/SPAN&gt;)&lt;BR&gt;#&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;If&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DoThirdThing()&lt;BR&gt;#&lt;SPAN style="COLOR: blue"&gt;If&lt;/SPAN&gt; DEBUG &lt;SPAN style="COLOR: blue"&gt;Then&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LogMessage(&lt;SPAN style="COLOR: #a31515"&gt;"Did third thing"&lt;/SPAN&gt;)&lt;BR&gt;#&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;If&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;BR&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Class&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;This code is&amp;nbsp;obviously difficult to read. However, using partial methods it is possible to make the code much more readable:&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Class&lt;/SPAN&gt; PrettyConditonalCompilationCode&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Partial&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; LogMessage(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; s &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;String&lt;/SPAN&gt;)&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;#&lt;SPAN style="COLOR: blue"&gt;If&lt;/SPAN&gt; DEBUG &lt;SPAN style="COLOR: blue"&gt;Then&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; LogMessage(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; s &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;String&lt;/SPAN&gt;)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(s)&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;BR&gt;&lt;/SPAN&gt;#&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;If&lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Sub&lt;/SPAN&gt; DoStuff()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DoFirstThing()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LogMessage(&lt;SPAN style="COLOR: #a31515"&gt;"Did first thing"&lt;/SPAN&gt;)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DoSecondThing()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LogMessage(&lt;SPAN style="COLOR: #a31515"&gt;"Did second thing"&lt;/SPAN&gt;)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DoThirdThing()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LogMessage(&lt;SPAN style="COLOR: #a31515"&gt;"Did third thing"&lt;/SPAN&gt;)&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;BR&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Class&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;&lt;BR&gt;&lt;STRONG&gt;Are Partial Methods Some Form Of AOP (Aspect Oriented Programming)? &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;No. Partial methods do share some things in common with Aspect Oriented Programming in that partial methods offer a way of associating "hooks" with custom code. However, unlike AOP systems partial methods require extension points to be explicitly defined by the customer. AOP systems allow developers to "weave in" functionality into code that hasn't had explicit hooks defined. Usually they do this by specifying some declarative search strings that describes the places where the hooks should be applied. The compiler is then responsible for finding all the appropriate "extension points" to apply the hooks to and injecting any necessary method calls. Partial methods in VB do not do this.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1971409" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/vbteam/archive/tags/Scott+Wisniewski/default.aspx">Scott Wisniewski</category></item><item><title>Extension Methods Best Practices (Extension Methods Part 6)</title><link>http://blogs.msdn.com/vbteam/archive/2007/03/10/extension-methods-best-practices-extension-methods-part-6.aspx</link><pubDate>Sun, 11 Mar 2007 02:36:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1855898</guid><dc:creator>VBTeam</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/vbteam/comments/1855898.aspx</comments><wfw:commentRss>http://blogs.msdn.com/vbteam/commentrss.aspx?PostID=1855898</wfw:commentRss><description>&lt;P&gt;This is the sixth installment in my series of posts about extension methods. You can find links to the rest of the series &lt;A href="http://blogs.msdn.com/vbteam/pages/articles-about-extension-methods.aspx" mce_href="http://blogs.msdn.com/vbteam/pages/articles-about-extension-methods.aspx"&gt;here&lt;/A&gt;. &lt;/P&gt;
&lt;P&gt;Today I am going to talk about some best practices for using extension methods. Most of this content is geared toward authors of class libraries designed for wide spread consumption. Developers of such libraries often need to worry about things like making their API's future proof, and finding ways to extend their libraries while still preserving backwards compatibility. &lt;STRONG&gt;In most real world applications these suggestions can (and quite frankly should!) be completely ignored&lt;/STRONG&gt;. However, if you are in the business of creating components or libraries used by many developers, than heeding this advice should help to ensure that your consumers, particularly those using VB, have a pleasant experience with your API. &lt;/P&gt;&lt;EM&gt;&lt;STRONG&gt;1. Read the .NET Framework Class Library Design Guidelines&lt;/STRONG&gt; &lt;/EM&gt;
&lt;P&gt;&lt;EM&gt;The .NET Framework Class Library Design Guidelines&lt;/EM&gt;, available &lt;A href="http://msdn2.microsoft.com/en-us/library/ms229042.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms229042.aspx"&gt;here&lt;/A&gt;, provide guidance on how to write highly usable, secure, and extensible class libraries for the .NET Framework. Also, &lt;A href="http://blogs.msdn.com/brada/" mce_href="http://blogs.msdn.com/brada/"&gt;Brad Abrams&lt;/A&gt; and &lt;A href="http://blogs.msdn.com/kcwalina/" mce_href="http://blogs.msdn.com/kcwalina/"&gt;Krzysztof Cwalina&lt;/A&gt; wrote a &lt;A href="http://www.amazon.com/exec/obidos/tg/detail/-/0321246756/qid=1123679961/sr=8-1/ref=sr_8_xs_ap_i1_xgl14?v=glance&amp;amp;s=books&amp;amp;n=507846&amp;amp;tag2=bradabramsblo-20" mce_href="http://www.amazon.com/exec/obidos/tg/detail/-/0321246756/qid=1123679961/sr=8-1/ref=sr_8_xs_ap_i1_xgl14?v=glance&amp;amp;s=books&amp;amp;n=507846&amp;amp;tag2=bradabramsblo-20"&gt;book&lt;/A&gt; on how to do this. You should check them out. &lt;/P&gt;&lt;EM&gt;&lt;STRONG&gt;2. Be wary of extension methods&lt;/STRONG&gt; &lt;/EM&gt;
&lt;P&gt;For an application programmer, extension methods are an incredibly powerful and expressive tool. They enable convenience, extensibility, and an improved intellisence experience. However, many of the features that make extension methods so useful for library consumers can be problematic for class library authors. In particular, there are 2 primary issues I outline below that you should be aware of when using extension methods in class libraries, particularly for mass-market libraries that need to maintain backwards compatibility across multiple releases. &lt;/P&gt;
&lt;P&gt;The first issue is that extension methods have "hide-by-name" semantics with instance members on a type. This means that any accessible instance member on a type will always shadow any extension methods with the same name, even if the extension method is a better fit (see &lt;A href="http://blogs.msdn.com/vbteam/archive/2007/01/24/extension-methods-and-late-binding-extension-methods-part-4.aspx" mce_href="http://blogs.msdn.com/vbteam/archive/2007/01/24/extension-methods-and-late-binding-extension-methods-part-4.aspx"&gt;part 4&lt;/A&gt; for details). As a result, if an instance member is ever added to a type with the same name as an extension method, then the extension method can be rendered uncallable. This can make extension method libraries somewhat fragile. &lt;/P&gt;
&lt;P&gt;The second issue is that an extension method author cannot prevent other programmers from writing conflicting extensions. Instance method authors can mark their classes as "notinheritable" and prevent them from being augmented by derived classes. Similarly, methods marked as "overridable" in abstract base classes can be marked as "notoverridable" when they are overridden in a derived class, disallowing them from being overridden by classes further down in the hierarchy. Instance methods cannot be overridden by extension methods. These things give class library authors certain degrees of certainty about which instance methods will be called in which situations. Unfortunately, however, extension method authors have no such guarantees. If a library user brings a third party extension method with the same name as yours into scope then that method may be preferred over yours. As a library author there is nothing you can do to prevent this. &lt;/P&gt;
&lt;P&gt;As a result, you should be cautious when adding extension methods to your class libraries unless either: &lt;/P&gt;
&lt;OL style="MARGIN-LEFT: 54pt"&gt;
&lt;LI&gt;These risks are unimportant (as is the case with most internal libraries), or &lt;/LI&gt;
&lt;LI&gt;You take steps to mitigate them as outlined in the rest of this article &lt;/LI&gt;&lt;/OL&gt;&lt;EM&gt;&lt;STRONG&gt;3. Put extension methods into their own namespace&lt;/STRONG&gt; &lt;/EM&gt;
&lt;P&gt;One simple way to improve the robustness of your extension method library is to put extension methods into their own namespace. This is the strategy employed by the 3.5 version of the .NET Framework. By putting extension methods into their own namespace you enable consumers to include or exclude them separately from the rest of your library. This makes them pluggable, allowing users to easily replace extension method implementations with other implementations if they wish (which is at the heart of the LINQ provider model). This in turn then makes it easier for them to resolve any conflicts that may arise (see &lt;A href="http://blogs.msdn.com/vbteam/archive/2007/01/11/extension-methods-part-2.aspx" mce_href="http://blogs.msdn.com/vbteam/archive/2007/01/11/extension-methods-part-2.aspx"&gt;part 2&lt;/A&gt; for information about extension method precedence levels). &lt;BR&gt;&lt;BR&gt;&lt;EM&gt;&lt;STRONG&gt;4. Think twice before extending types you don't own &lt;/STRONG&gt;&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;If you only write extension methods for types you own, then you never have to worry about your extensions being broken by changes to the type being extended. On the other hand, if you are extending other peoples types than you are essentially at their mercy. Alternatively, you can minimize this risk by choosing names that are unlikely to be used by someone else, or by minimizing the total number of extension methods you define (i.e reducing surface area). One technique for doing this may be to write one extension method that converts the underlying object to a different type that is controlled by you. &lt;/P&gt;&lt;EM&gt;&lt;STRONG&gt;5. Prefer interface extensions over class extensions&lt;/STRONG&gt; &lt;/EM&gt;
&lt;P&gt;This may seem like odd advice, given that the &lt;EM&gt;The .NET Framework Class Library Design Guidelines&lt;/EM&gt; referenced above state that you should "prefer classes to interfaces". However, the reasons for advocating interface extensions over class extensions are identical to the reasons for advocating the use of classes over the user of interfaces in that document: interfaces cannot be safely versioned. In other words, an interface cannot be changed without requiring every class that implements it to be modified. This means that, for the most part, as a class library author you can treat interfaces as immutable types (if they do change, all their clients will be broken anyways, so you can't make the problem any worse). Classes, on the other hand, can add new methods without breaking their clients, which is why the design guidelines recommend them (at least they could prior to the introduction of extension methods, and so to be safe you should assume that other class library authors may continue to follow that convention). As a result, interface extensions are inherently less fragile than class extensions. &lt;/P&gt;
&lt;P&gt;This isn't perfect, as interface extensions can be visible from instances of implementing classes, which may then change in future versions by adding new methods. However, these issues can always be worked around by casting any such classes to instances of the interface. With class extensions, such a workaround may not be possible. &lt;/P&gt;&lt;EM&gt;&lt;STRONG&gt;6. Be as specific with the types you extend as possible&lt;/STRONG&gt; &lt;/EM&gt;
&lt;P&gt;Extensions on less specific types are more likely to be broken by external change than extensions on more specific types. This is because the higher a type is in the hierarchy, the more types there are that derive from it. An extension method on type "Object" can be broken by the introduction of any member to any type anywhere. An extension method on "string", on the other hand, can only be broken by changes to string or other extension methods. Therefore, by preferring more specific types, you can reduce the likely hood of other people's changes impacting your API. This is a little at odds with item #5, as interfaces are by definition less specific than classes. As a library author you would have to find the right balance between them. &lt;/P&gt;&lt;EM&gt;&lt;STRONG&gt;7. Please ignore this advice where it is not appropriate&lt;/STRONG&gt;&lt;/EM&gt; 
&lt;P&gt;I mentioned this at the beginning of the post, but I thought it was worth pointing out again: for most programs you should ignore this advice. Adding extension methods to any type is a great way to improve productivity and simplify code. You should do this wherever it feels beneficial to you, without worrying about any of these details. However, if you need to write an API that can be consumed by a lot of programmers (say thousands or even millions), then I think it's worthwhile for you to consider these constraints in your designs. &lt;/P&gt;
&lt;P&gt;That's all I have for today. Stay tuned for my next post where I will break away from extension methods and start to talk about some of the other cool features we are introducing into the language. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1855898" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/vbteam/archive/tags/LINQ_2F00_VB9/default.aspx">LINQ/VB9</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/Scott+Wisniewski/default.aspx">Scott Wisniewski</category></item><item><title>March 2007 Orcas CTP Available</title><link>http://blogs.msdn.com/vbteam/archive/2007/02/28/march-2007-orcas-ctp-available.aspx</link><pubDate>Thu, 01 Mar 2007 05:46:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1776975</guid><dc:creator>VBTeam</dc:creator><slash:comments>13</slash:comments><comments>http://blogs.msdn.com/vbteam/comments/1776975.aspx</comments><wfw:commentRss>http://blogs.msdn.com/vbteam/commentrss.aspx?PostID=1776975</wfw:commentRss><description>&lt;P&gt;The&amp;nbsp;March 2007 Orcas CTP is now available for download.&lt;/P&gt;
&lt;P&gt;You can see Soma's anouncement about it &lt;A class="" href="http://blogs.msdn.com/somasegar/archive/2007/02/28/visual-studio-orcas-march-ctp-is-available-now.aspx" mce_href="http://blogs.msdn.com/somasegar/archive/2007/02/28/visual-studio-orcas-march-ctp-is-available-now.aspx"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;This is the first Orcas CTP to include new VB 9.0 features and is the first update of VB&amp;nbsp;LINQ since last year's May 2006 LINQ CTP.&lt;/P&gt;
&lt;P&gt;Amongst a lot of other really cool Orcas stuff, this CTP includes previews of the following VB 9.0 features:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Basic Query Support&lt;/LI&gt;
&lt;LI&gt;Object Initializers&lt;/LI&gt;
&lt;LI&gt;Extension Methods&lt;/LI&gt;
&lt;LI&gt;Type Inference&lt;/LI&gt;
&lt;LI&gt;Anonymous Types&lt;/LI&gt;
&lt;LI&gt;XML Literals&lt;/LI&gt;
&lt;LI&gt;XML Access Members&lt;/LI&gt;
&lt;LI&gt;Some Really Cool Intellisence Enhancements&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;You can download&amp;nbsp;it &lt;A class="" href="http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx" mce_href="http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Also, downloading the CTP is a great way to checkout the things I've been talking about in my recent posts about &lt;A class="" href="http://blogs.msdn.com/vbteam/pages/articles-about-extension-methods.aspx" mce_href="http://blogs.msdn.com/vbteam/pages/articles-about-extension-methods.aspx"&gt;extension methods&lt;/A&gt;.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1776975" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/vbteam/archive/tags/Scott+Wisniewski/default.aspx">Scott Wisniewski</category></item><item><title>Extension methods and Generics (Extension Methods Part 5)</title><link>http://blogs.msdn.com/vbteam/archive/2007/02/15/extension-methods-and-generics-extension-methods-part-5.aspx</link><pubDate>Fri, 16 Feb 2007 00:40:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1685854</guid><dc:creator>VBTeam</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/vbteam/comments/1685854.aspx</comments><wfw:commentRss>http://blogs.msdn.com/vbteam/commentrss.aspx?PostID=1685854</wfw:commentRss><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;This is the 5th installment in my series of posts about extension methods. You can find links to the rest of the series &lt;A href="http://blogs.msdn.com/vbteam/pages/articles-about-extension-methods.aspx"&gt;&lt;SPAN style="COLOR: blue; mso-bidi-font-size: 11.0pt"&gt;here&lt;/SPAN&gt;&lt;/A&gt;. Originally I had planned on discussing extension method versioning issues, but I've decided to postpone that topic to my next post and talk about extension methods and generics instead. &lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;In Orcas we've introduced a new set of rules for the way we deal with generic extension methods that differs significantly from the way we deal with regular generic methods. When binding against extension methods we now perform generic type parameter inference in two passes instead of one. During the first pass we infer types for type parameters referenced by the first argument and during the second pass we infer types for any type parameters referenced by subsequent arguments. Internally we have been referring to this as "partial type inference" in our discussions about it. As an example, consider the following: &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'"&gt;Imports&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'"&gt; System.Runtime.CompilerServices&amp;nbsp;&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;Module&lt;/SPAN&gt; M1&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;Interface&lt;/SPAN&gt; IFoo(&lt;SPAN style="COLOR: blue"&gt;Of&lt;/SPAN&gt; T1, T2)&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Interface&amp;nbsp;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&amp;lt;Extension()&amp;gt; _&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;Public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Bar(&lt;SPAN style="COLOR: blue"&gt;Of&lt;/SPAN&gt; T1, T2, T3)(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; x &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; IFoo(&lt;SPAN style="COLOR: blue"&gt;Of&lt;/SPAN&gt; T1, T3), &lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; y &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; T2, &lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; z &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; T3)&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&amp;nbsp;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Sub&lt;/SPAN&gt; Main()&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;Dim&lt;/SPAN&gt; x &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; IFoo(&lt;SPAN style="COLOR: blue"&gt;Of&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Integer&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;String&lt;/SPAN&gt;) = &lt;SPAN style="COLOR: blue"&gt;Nothing&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;x.Bar(&lt;SPAN style="COLOR: #a31515"&gt;"Hello"&lt;/SPAN&gt;, 2)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Bar(x, &lt;SPAN style="COLOR: #a31515"&gt;"Hello"&lt;/SPAN&gt;, 2)&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;BR&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Module&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;Using the Whidbey type inference algorithm the &lt;EM&gt;&lt;STRONG&gt;instance method call&lt;/STRONG&gt;&lt;/EM&gt; to Bar in Main would result in a compile time error. Attempting to resolve all types in one pass, the compiler would infer two conflicting types for T3, one from parameter X and another from parameter Z. With Orcas, however, the &lt;EM&gt;&lt;STRONG&gt;extension method&lt;/STRONG&gt;&lt;/EM&gt; call to Bar will not generate an error. Instead, the compiler will first infer types for T1 and T3 from parameter x and then substitute their values back into the procedure's signature. During the second pass of type inference the compiler will then treat the method as if it was a method with only one type parameter rather than a method with three type parameters. A value will be inferred for T3 from Z and then a conversion will be inserted to convert the integer arguments supplied to&amp;nbsp;Y into the string value expected by the procedure. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;Although this may seem like a complicated and perplexing rule, there is a bit of method to our madness. In particular it enables us to: &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-list: l0 level1 lfo1; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list .5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;Maintain transparency between extension methods and instance methods &lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-list: l0 level1 lfo1; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list .5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;Avoid generating misleading intellisence information. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-list: l0 level1 lfo1; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list .5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;Produce a better query-editing experience &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;Each of these reasons is discussed in detail below: &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-outline-level: 3"&gt;&lt;B&gt;&lt;SPAN style="FONT-SIZE: 13.5pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;Extension Method Transparency &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;To see why the first reason is true is, let's consider the following: &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'"&gt;&amp;lt;Extension()&amp;gt; _ &lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; InsertTwice(&lt;SPAN style="COLOR: blue"&gt;Of&lt;/SPAN&gt; T)(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; x &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; ICollection(&lt;SPAN style="COLOR: blue"&gt;Of&lt;/SPAN&gt; T), &lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; y &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; T) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; x.Add(y) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; x.Add(y) &lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;Here we define an extension method named "InsertTwice" that applies to all implementations of the generic ICollection(of T) interface. Its implementation is rather trivial. That thing about it that &lt;/SPAN&gt;&lt;B&gt;&lt;I&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt"&gt;is&lt;/SPAN&gt;&lt;/I&gt;&lt;/B&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt; interesting is that its type parameter T is, in a sense, more of a "generic type parameter" than a "generic method parameter". Its primary purpose is to define the types of the objects to which the method is applicable, rather than to define the signature of the method itself. The fact that the there is a dependency between the method's signature and its "containing" class is a peculiarity of the method, not of the type parameter. The parameter's primary function is still to define the type. An alternative way to look at it is to consider how the method would look if it was defined as an&amp;nbsp;instance method rather than as an extension method.&amp;nbsp;Had "InsertTwice" been defined as instance method T would almost certainly be defined as a type parameter on a class rather than as a type parameter on a method. The need for T to be defined as a method parameter is simply just a side effect of the syntax to define extension methods. In fact, using this point of view it becomes clear that &lt;/SPAN&gt;&lt;B&gt;&lt;I&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt"&gt;all&lt;/SPAN&gt;&lt;/I&gt;&lt;/B&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt; type parameters referenced by the first argument of &lt;/SPAN&gt;&lt;B&gt;&lt;I&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt"&gt;any&lt;/SPAN&gt;&lt;/I&gt;&lt;/B&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt; extension method really are &lt;/SPAN&gt;&lt;B&gt;&lt;I&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt"&gt;generic type parameters&lt;/SPAN&gt;&lt;/I&gt;&lt;/B&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt; rather than &lt;/SPAN&gt;&lt;B&gt;&lt;I&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt"&gt;generic method parameters&lt;/SPAN&gt;&lt;/I&gt;&lt;/B&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;. The goal of the compiler then, by splitting the inference up into two distinct steps, is really to restore things back to their correct state. The generic type parameters get treated as type parameters (they are inferred solely from the "me" parameter), and the generic method parameters get treated as method parameters (they are inferred from the method's arguments). &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;This does have some interesting implications. Mainly, it is now possible to invoke a generic method with some arguments explicitly provided and other arguments implicitly inferred. In particular, any type parameters that are determined to represent generic type parameters (because they are referenced by the first argument) are always implicitly inferred from the type of the object that the method was invoked on. The remaining type parameters, which are treated as generic method parameters, may then be explicitly supplied by the caller if necessary. However, the old Whidbey rules still apply to the group of parameters that are determined to belong to the method. Effectively, although it's possible to implicitly infer the "type" parameters and explicitly supply the "method" parameters, it is not possible to implicitly infer some method parameters and explicitly supply others. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-outline-level: 3"&gt;&lt;B&gt;&lt;SPAN style="FONT-SIZE: 13.5pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;Intellisence Usability &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;Moving on to reason #2 in our list above, this also fixes a small issue with intellisence. At the heart of our intellisence design is the principal that we never guide the user towards generating compiler errors. If an item shows up in a completion list in a given context then it is valid to use that item in that context. When we show information in a tool tip it is always up to date and accurate. This is really just an example of the IDE trying both to be nice and to avoid looking stupid. If we were to offer you something and then start to complain immediately after you selected it, then we would appear to not only be rude, but also to be stupid. This also means you can trust what the compiler tells you. If our "find symbol" says something doesn't exist or our "find all references" says something isn't used, then it doesn't exist or it isn't referenced. Similarly, if something does exists, or is being referenced somewhere in your code than we will report those things to you. If we show a tool tip, then the data in that tool tip is correct. At least that's how we design things to be. Realistically there always will be bugs that slip through the cracks, or things that aren't 100% perfect. However, we try our best to make the information that we give you as useful as possible. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;Before we implemented the two step process for generic type inference in intellisence, some of the information we would show in intellisence was a bit misleading. Technically it &lt;/SPAN&gt;&lt;B&gt;&lt;I&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt"&gt;was&lt;/SPAN&gt;&lt;/I&gt;&lt;/B&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt; accurate but it was much less useful than it could be. To illustrate this, let's consider our "InsertTwice" example from above. If we were to invoke the method using the following code snippet: &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'"&gt;Sub&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'"&gt; Main() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;Dim&lt;/SPAN&gt; x &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;New&lt;/SPAN&gt; List(&lt;SPAN style="COLOR: blue"&gt;Of&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;String&lt;/SPAN&gt;) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; x.InsertTwice( &lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;Then without our new rules we would end up showing a parameter info tool tip that looked like the following: &lt;BR&gt;&lt;BR&gt;&lt;IMG style="WIDTH: 322px; HEIGHT: 81px" height=81 src="http://vbteam.members.winisp.net/blog/scottwis/ExtensionMethodInvocationWithoutPartialTypeInference.jpg" width=322 border=1 mce_src="http://vbteam.members.winisp.net/blog/scottwis/ExtensionMethodInvocationWithoutPartialTypeInference.jpg"&gt;&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="mso-no-proof: yes"&gt;&lt;?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /&gt;&lt;v:shapetype id=_x0000_t75 coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"&gt;&lt;v:stroke joinstyle="miter"&gt;&lt;/v:stroke&gt;&lt;v:formulas&gt;&lt;v:f eqn="if lineDrawn pixelLineWidth 0"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum @0 1 0"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum 0 0 @1"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @2 1 2"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @3 21600 pixelWidth"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @3 21600 pixelHeight"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum @0 0 1"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @6 1 2"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @7 21600 pixelWidth"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum @8 21600 0"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @7 21600 pixelHeight"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum @10 21600 0"&gt;&lt;/v:f&gt;&lt;/v:formulas&gt;&lt;v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"&gt;&lt;/v:path&gt;&lt;o:lock v:ext="edit" aspectratio="t"&gt;&lt;/o:lock&gt;&lt;/v:shapetype&gt;&lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;This, however, is a bit misleading. It indicates that InsertTwice is a generic method that can take an argument of any type T. This is, however, not true. The type of the argument is actually fixed to be string. Supplying any argument that was not String would yield a generic type inference error. More importantly, this error would then lead the author of this code to believe that he could fix the problem by explicitly providing the type of T: &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;x.InsertTwice(&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'"&gt;Of&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'"&gt; &lt;SPAN style="COLOR: blue"&gt;String&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;) &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;However, this would only end up generating yet another generic type inference error, mainly because types inferred from x would then conflict with types inferred from y. &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;Obviously this hurt the usability of intellisence. With our new rules, however, we end up showing a parameter info tooltip that looks like this: &lt;BR&gt;&lt;BR&gt;&lt;IMG style="WIDTH: 295px; HEIGHT: 82px" height=82 src="http://vbteam.members.winisp.net/blog/scottwis/ExtensionMethodInvocationWithPartialTypeInference.jpg" width=295 border=1 mce_src="http://vbteam.members.winisp.net/blog/scottwis/ExtensionMethodInvocationWithPartialTypeInference.jpg"&gt;&lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-no-proof: yes; mso-fareast-font-family: 'Times New Roman'"&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;This is clearly much more useful. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-outline-level: 3"&gt;&lt;B&gt;&lt;SPAN style="FONT-SIZE: 13.5pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;Improved Query Support &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;The third, and perhaps most important, reason behind this decision is that it had a tremendous positive impact on our ability to support a good experience around using LINQ with VB. To see why, let’s consider a simple example: &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'"&gt;Imports&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'"&gt; System.Linq &lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;Module&lt;/SPAN&gt; M1 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Main() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;Dim&lt;/SPAN&gt; xs &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Integer&lt;/SPAN&gt;() = {1, 2, 3, 4} &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;Dim&lt;/SPAN&gt; q = &lt;SPAN style="COLOR: blue"&gt;From&lt;/SPAN&gt; x &lt;SPAN style="COLOR: blue"&gt;In&lt;/SPAN&gt; xs &lt;SPAN style="COLOR: blue"&gt;Where&lt;/SPAN&gt; x &lt;SPAN style="COLOR: blue"&gt;Mod&lt;/SPAN&gt; 2 = 0 &lt;SPAN style="COLOR: blue"&gt;Select&lt;/SPAN&gt; x &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;BR&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Module&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;Here we define a simple query that selects all even integers out of an array. When processing this query the compiler converts into the equivalent of the following code: &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'"&gt;Dim&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'"&gt; q = xs.Where(&lt;SPAN style="COLOR: blue"&gt;Function&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; x) x &lt;SPAN style="COLOR: blue"&gt;Mod&lt;/SPAN&gt; 2).Select(&lt;SPAN style="COLOR: blue"&gt;Function&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; x) x)&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;Which invokes 2 extension methods, one called Where that takes in a lambda that corresponds to the contents of the where clause, and another called select that takes in a lambda that corresponds to the contents of the select clause. As these queries are being typed the compiler will provide intellisence within each clause. Doing so, of course, requires identifying the element type of the collection being queried over so that its members may be appropriately shown in intellisence completion lists. Our new typing rules help make this easy. If we look at the signature of the Where method we can see why this is: &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'"&gt;Public&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'"&gt; &lt;SPAN style="COLOR: blue"&gt;Function&lt;/SPAN&gt; Where(&lt;SPAN style="COLOR: blue"&gt;Of&lt;/SPAN&gt; T)(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; source &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; IEnumerable(&lt;SPAN style="COLOR: blue"&gt;Of&lt;/SPAN&gt; T), &lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; predicate &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; Func(&lt;SPAN style="COLOR: blue"&gt;Of&lt;/SPAN&gt; T, &lt;SPAN style="COLOR: blue"&gt;Boolean&lt;/SPAN&gt;)) &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; IEnumerable(&lt;SPAN style="COLOR: blue"&gt;Of&lt;/SPAN&gt; T)&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;It defines an extension method that is applicable to all implementations of the IEnumerable(of T) interface, taking in delegate that maps from type T to Boolean and returns another IEnumerable of the same type. If the old Whidbey rules were used to perform type inference on the call to Where, it would not be possible to determine the element type T of the collection until the entire where clause of the query had been processed, because the body of the where clause needs to be converted into a lambda and then wrapped up in a delegate type and passed off to the procedure as an argument. However, in order to assist query authors in writing a where clause, the IDE must be able to deduce the element type of the collection. This creates a obvious chicken-and-egg-situation: it becomes necessary to determine the value of T in order to be able to determine the value of T. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;However, with our new rules this problem doesn't exist. With the new rules we can determine the element type of a collection just by looking at the collection its self, without expliciting having to bind all sub expressions first. This, of course, then makes it easy for us to provide accurate and useful intellisence inside our queries. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-outline-level: 3"&gt;&lt;B&gt;&lt;SPAN style="FONT-SIZE: 13.5pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;Caveats &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;Unfortunately, this does introduce a few minor issues that you need to be aware of. Mainly: &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL type=1&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-list: l1 level1 lfo2; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list .5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;Type parameters referenced by the first argument of an extension method may not be constrained by other type parameters that are not referenced by the first parameter of an extension method. This means that while the following extension methods would be legal:&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'"&gt;&lt;BR&gt;&amp;lt;Extension()&amp;gt; _&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; M1(&lt;SPAN style="COLOR: blue"&gt;Of&lt;/SPAN&gt; T1, T2)(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; x &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; T1)&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'"&gt;&amp;lt;Extension()&amp;gt; _&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; M2(&lt;SPAN style="COLOR: blue"&gt;Of&lt;/SPAN&gt; T1, T2 &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; T1)(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; x &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; IFoo(&lt;SPAN style="COLOR: blue"&gt;Of&lt;/SPAN&gt; T1, T2))&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;&lt;BR&gt;&lt;BR&gt;that this one, on the other hand, would not:&lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'"&gt;&amp;lt;Extension()&amp;gt; _&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'"&gt;Sub&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'"&gt; M3(&lt;SPAN style="COLOR: blue"&gt;Of&lt;/SPAN&gt; T1, T2 &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; T1)(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; x &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; T2)&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-list: l1 level1 lfo2; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list .5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;C# does not implement these rules, so any extension methods defined in C# that violate the above restriction will not be visible to VB programmers. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;In general, however, we feel that these restrictions are largely outweighed by the benefits these rules introduce. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-outline-level: 3"&gt;&lt;B&gt;&lt;SPAN style="FONT-SIZE: 13.5pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;Side Note &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;On a side note, the instance method call I mention in my first example will also no longer be an error in Orcas. This, however, has to do with a different change we are introducing to resolve type inference conflicts that I won't delve into with this post. It is sufficient, however, to note that the rules for type inference in the instance method case will continue to use an "infer-everything-at-once-approach", where as extension methods will use the two step algorithm I outline here. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;In any case, I think that's enough for today. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'; mso-fareast-font-family: 'Times New Roman'"&gt;Stay tuned for my next post, where I will discuss some best practices for using extension methods in your programs. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1685854" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/vbteam/archive/tags/LINQ_2F00_VB9/default.aspx">LINQ/VB9</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/Scott+Wisniewski/default.aspx">Scott Wisniewski</category></item><item><title>Extension methods and late binding (Extension Methods Part 4)</title><link>http://blogs.msdn.com/vbteam/archive/2007/01/24/extension-methods-and-late-binding-extension-methods-part-4.aspx</link><pubDate>Thu, 25 Jan 2007 01:09:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1523828</guid><dc:creator>VBTeam</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/vbteam/comments/1523828.aspx</comments><wfw:commentRss>http://blogs.msdn.com/vbteam/commentrss.aspx?PostID=1523828</wfw:commentRss><description>&lt;P&gt;This is the fourth installment in my series of posts about extension methods. You can find links to the rest of the series &lt;A href="http://blogs.msdn.com/vbteam/pages/articles-about-extension-methods.aspx" mce_href="http://blogs.msdn.com/vbteam/pages/articles-about-extension-methods.aspx"&gt;here&lt;/A&gt;. &lt;/P&gt;
&lt;P&gt;Today I'm going to talk about extension methods and late binding. Essentially there isn't much to say about it, other than the fact that we don't support late bound execution of extension methods. For the most part this isn't a big deal as one of the primary benefits of extension methods is its interaction with intellisence which doesn't work in late bound scenarios anyways. Unfortunately, however, there is one big side effect of this decision that you need to be aware of when authoring extension methods. Mainly, we do not allow extension methods to be called off of any expression that is statically typed as "Object". This was necessary to prevent any existing late bound code you may have written from being broken by extension methods. Too see why, consider the following example: &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Class&lt;/SPAN&gt; C1&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Method1() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;Console.WriteLine(&lt;SPAN style="COLOR: #a31515"&gt;"Running c1.Method1"&lt;/SPAN&gt;) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Class &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Class&lt;/SPAN&gt; C2 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Method1() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;Console.WriteLine(&lt;SPAN style="COLOR: #a31515"&gt;"Running c2.Method1"&lt;/SPAN&gt;) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Class &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Module&lt;/SPAN&gt; M1 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Main() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Dim&lt;/SPAN&gt; x &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Object&lt;/SPAN&gt; = &lt;SPAN style="COLOR: blue"&gt;Nothing&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;If&lt;/SPAN&gt; (SomeCondition()) &lt;SPAN style="COLOR: blue"&gt;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; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;x = &lt;SPAN style="COLOR: blue"&gt;New&lt;/SPAN&gt; C1 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;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; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;x = &lt;SPAN style="COLOR: blue"&gt;New&lt;/SPAN&gt; C2 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;If &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;x.Method1()&amp;nbsp;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;FONT color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;BR&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Module &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Here we have a program which uses late binding in order to invoke the method "Method1" on an object that is either of type "c1" or of type "c2". It does this because the static type of the variable "x" is declared as object, which causes the compiler to resolve any calls to "unknown" methods as late bound calls that will be resolved at runtime based on the dynamic type of the object stored in "x". Extension methods, however, are always fully resolved at compile time. As a result, if we were to add an extension method defined on Object, like so: &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;lt;Extension()&amp;gt; _ &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Method1(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; x &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Object&lt;/SPAN&gt;) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;Console.WriteLine(&lt;SPAN style="COLOR: #a31515"&gt;"Running Extension method m1.Method1"&lt;/SPAN&gt;) &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Then the act of simply importing the namespace containing the method would cause the formerly late bound method call to Method1 to be transformed into an early bound call to the extension method. This would not be good, as it would silently change the meaning of the program, which would have the potential of making extension methods very, very dangerous. In fact, we explicitly disallow this in early bound scenarios by always having instance methods defined on a type shadow any extension methods defined on it with the same name. This enables you to import extension methods into your existing code without having to worry about things blowing up in your face. &lt;/P&gt;
&lt;P&gt;In the case of late bound calls, however, we can't use the same shadowing semantics that we do with early bound method calls because we don't know the actual type of the object we will be calling the method on, so we don't have a list of methods we can check against at compile time. As a result, the only way we could prevent extension methods from completely breaking existing late bound code was to prevent them from being used on anything typed as object. &lt;/P&gt;
&lt;P&gt;This has the effect of slightly changing the meaning of an extension method defined on object. Consider the following non-object extension method: &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;lt;Extension()&amp;gt; _ &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Method2(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; x &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; System.Windows.Forms.Control) &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Here the declaration of "Method2" implies that the method is an extension method applicable to the type System.Windows.Froms.Control and any class that derives from it, such as TextBox or DataGridView. In the case of "Method1", however, the method declaration implies that it is applicable to "all types &lt;STRONG&gt;&lt;EM&gt;except&lt;/EM&gt;&lt;/STRONG&gt; object". This is a little unfortunate, as it is an inconsistency in the language, but we felt it was much better in this case to be safe than it was to be consistent. &lt;/P&gt;
&lt;P&gt;That's all I have for today. In my next post I'll talk about extension methods and generics. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1523828" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/vbteam/archive/tags/Scott+Wisniewski/default.aspx">Scott Wisniewski</category></item><item><title>Extension Methods (part 3)</title><link>http://blogs.msdn.com/vbteam/archive/2007/01/18/extension-methods-part-3.aspx</link><pubDate>Fri, 19 Jan 2007 08:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1491808</guid><dc:creator>VBTeam</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/vbteam/comments/1491808.aspx</comments><wfw:commentRss>http://blogs.msdn.com/vbteam/commentrss.aspx?PostID=1491808</wfw:commentRss><description>&lt;P&gt;In my previous 2 posts I talked about some of the &lt;A href="http://blogs.msdn.com/vbteam/archive/2007/01/05/extension-methods-part-1.aspx" mce_href="http://blogs.msdn.com/vbteam/archive/2007/01/05/extension-methods-part-1.aspx"&gt;benefits&lt;/A&gt; of extension methods and then delved into the details of our &lt;A href="http://blogs.msdn.com/vbteam/archive/2007/01/11/extension-methods-part-2.aspx?" mce_href="http://blogs.msdn.com/vbteam/archive/2007/01/11/extension-methods-part-2.aspx?"&gt;new binding rules&lt;/A&gt; for consuming them in your programs. Today I'm going to talk about some perils to be aware of when defining extension methods. &lt;/P&gt;
&lt;P&gt;First, however, I'm going to dig a little into the mechanics used by the compiler for evaluating extension method calls. Essentially, whenever the compiler detects a call to an extension method, it simply translates it into a call to the underlying module method, passing in the call's receiver as the method's first argument.&lt;BR&gt;&lt;BR&gt;If we take the following simple example: &lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Delegate&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; DelegateSub() &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;lt;Extension()&amp;gt; _&amp;nbsp;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Times(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; x &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Integer&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; d &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; DelegateSub) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;For&lt;/SPAN&gt; i = 1 &lt;SPAN style="COLOR: blue"&gt;To&lt;/SPAN&gt; x &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;d() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Courier New"&gt;Next &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;with the following call site: &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; SayHello() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;Console.WriteLine(&lt;SPAN style="COLOR: #a31515"&gt;"Hello"&lt;/SPAN&gt;) &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Main() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Call&lt;/SPAN&gt; 3.Times(&lt;SPAN style="COLOR: blue"&gt;AddressOf&lt;/SPAN&gt; SayHello) &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;The compiler will then emit code that is equivalent to the following: &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Main()&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;Times(3, &lt;SPAN style="COLOR: blue"&gt;AddressOf&lt;/SPAN&gt; SayHello) &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;/P&gt;
&lt;P&gt;For the most part this transformation is simple and automatic. In fact, we've taken great pains to ensure that the experience of calling an extension method on an object is as smooth as possible. Unfortunately, however, with value type extensions things get a little bumpy. To illustrate this, let's consider the following slightly more complex type:&lt;BR&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Structure&lt;/SPAN&gt; Vector &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Public&lt;/SPAN&gt; X &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Integer &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Public&lt;/SPAN&gt; Y &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Integer&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Public&lt;/SPAN&gt; Z &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Integer &lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Scale(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; factor &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Integer&lt;/SPAN&gt;) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;X *= factor &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;y *= factor &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;z *= factor &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Structure &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Here we define a method called "Scale" that mutates the current Vector, multiplying each of its members by the given scaling factor. As an instance method, this works fine. However, let's suppose we were to try and define "Scale2" as an Extension method: &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Module&lt;/SPAN&gt; Module1 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;lt;Extension()&amp;gt; _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Scale2(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; [me] &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; Vector, &lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; factor &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Integer&lt;/SPAN&gt;) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;[Me].X *= factor &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;[Me].y *= factor &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;[Me].z *= factor &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Module &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Calling this method will not have the same results as calling Scale. In particular, if we were to execute the following code: &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Main() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Dim&lt;/SPAN&gt; v &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; Vector&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;v.X = 1 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;v.Y = 1 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;v.Z = 1 &lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;Console.WriteLine(&lt;SPAN style="COLOR: #a31515"&gt;"v.x={0}, v.y={1}, v.z={2}"&lt;/SPAN&gt;, v.X, v.Y, v.Z)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; v.Scale2(2)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(&lt;SPAN style="COLOR: #a31515"&gt;"v.x={0}, v.y={1}, v.z={2}"&lt;/SPAN&gt;, v.X, v.Y, v.Z) &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;We would see that the value of v is unchanged after the call to Scale2. The reason for this is because value types have "value semantics", which means that unless they are passed as "byref" parameters they are copied every time they are passed to a procedure. As a result the extension method ends up mutating a copy of "v" rather than "v" itself. To fix this we need to declare the extension method with its "me" parameter declared "byref". &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;lt;Extension()&amp;gt; _ &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Scale2(&lt;SPAN style="COLOR: blue"&gt;ByRef&lt;/SPAN&gt; [me] &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; Vector, &lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; factor &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Integer&lt;/SPAN&gt;) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;[me].X *= factor&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;[me].Y *= factor &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;[me].Z *= factor &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;The "Scale2" extension method will then behave identically to the instance method version. &lt;/P&gt;
&lt;P&gt;Unfortunately, however, that doesn't mean extension methods with "byref" me parameters are without their own issues. This is especially true when defining extension methods on reference types. As an example, consider the following: &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Imports&lt;/SPAN&gt; System.Runtime.CompilerServices&amp;nbsp;&lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Class&lt;/SPAN&gt; C1 &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Class &lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Module&lt;/SPAN&gt; M1 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;lt;Extension()&amp;gt; _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; WeirdExtensionMethod(&lt;SPAN style="COLOR: blue"&gt;ByRef&lt;/SPAN&gt; x &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; C1, &lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; y &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; C1) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;x = y &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Main() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Dim&lt;/SPAN&gt; x &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;New&lt;/SPAN&gt; C1 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;x.WeirdExtensionMethod(&lt;SPAN style="COLOR: blue"&gt;Nothing&lt;/SPAN&gt;) &lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;If&lt;/SPAN&gt; (x &lt;SPAN style="COLOR: blue"&gt;Is&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Nothing&lt;/SPAN&gt;) &lt;SPAN style="COLOR: blue"&gt;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; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;Console.WriteLine(&lt;SPAN style="COLOR: #a31515"&gt;"X has magically become null. How did this happen?"&lt;/SPAN&gt;) &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;If &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Module &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Here we define an extension method that when called changes the reference of the variable it was called on. This has the potential of being very alarming to consumers of the method (generally calling a method on object doesn't cause the variable that holds the reference to suddenly point to another object). With extension methods, unfortunately, it is now possible to write code that does this. &lt;/P&gt;
&lt;P&gt;As we started development on the feature we briefly debated fixing both of these issues by requiring all value type extensions to have a byref me parameter and all reference type extensions to have a byval me parameter. However, enforcing this rule also meant we would have to make it illegal to define unconstrained generic extension methods like the following: &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;lt;Extension()&amp;gt; _ &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; GenericExtensionMethod(&lt;SPAN style="COLOR: blue"&gt;Of&lt;/SPAN&gt; T)(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; x &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; T) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: green"&gt;'... &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;However, we felt that this would unduly hurt interoperability between VB and other languages on the .NET platform that did not employ these restrictions. This was mainly because in the absence of these restrictions it is very natural to define methods like the one shown above. If we prevented these methods from being used in VB would then end up throwing out the vast majority of generic extension methods written in those languages. &lt;/P&gt;
&lt;P&gt;Unfortunately, this does mean that extension method authors need to be a little bit more cognizant of the methods they create. On the other hand it also enables VB programmers to use libraries written in other languages by programmers who may not be aware of any of the peculiarities of VB. Given that our design goals were centered on consumption rather than authoring, however, we felt this was a fair exchange. &lt;/P&gt;
&lt;P&gt;In any case, stay tuned for my next post, where I will discuss Extension Methods and Late Binding.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1491808" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/vbteam/archive/tags/LINQ_2F00_VB9/default.aspx">LINQ/VB9</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/Scott+Wisniewski/default.aspx">Scott Wisniewski</category></item><item><title>Extension Methods (part 2)</title><link>http://blogs.msdn.com/vbteam/archive/2007/01/11/extension-methods-part-2.aspx</link><pubDate>Fri, 12 Jan 2007 00:04:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1452112</guid><dc:creator>VBTeam</dc:creator><slash:comments>10</slash:comments><comments>http://blogs.msdn.com/vbteam/comments/1452112.aspx</comments><wfw:commentRss>http://blogs.msdn.com/vbteam/commentrss.aspx?PostID=1452112</wfw:commentRss><description>&lt;P&gt;In my previous post I gave a high level overview of some of the &lt;A href="http://blogs.msdn.com/vbteam/archive/2007/01/05/extension-methods-part-1.aspx" mce_href="http://blogs.msdn.com/vbteam/archive/2007/01/05/extension-methods-part-1.aspx"&gt;benefits&lt;/A&gt; of using Extension Methods in VB 9.0. Today I'm going to delve into some of the details about how to define extension methods and then use them in your programs. &lt;BR&gt;&lt;/P&gt;
&lt;H3&gt;Defining Extension Methods &lt;/H3&gt;
&lt;P&gt;&lt;BR&gt;You can define an extension method by creating a method in a VB module and decorating it with the System.Runtime.CompilerServices.Extension attribute. The type of the methods first parameter specifies the type the method extends, and the remaining arguments indicate the method's signature. In general, we allow an extension method to be defined on any type that can be represented in a VB signature, with the exception of param arrays, optional arguments, and generic type parameters to (because modules may not be generic). Specifically, this enables you to define extension methods on any of the following types: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Classes (Reference Types) &lt;/LI&gt;
&lt;LI&gt;Structures (Value Types) &lt;/LI&gt;
&lt;LI&gt;Interfaces &lt;/LI&gt;
&lt;LI&gt;Delegates &lt;/LI&gt;
&lt;LI&gt;ByRef / ByVal arguments &lt;/LI&gt;
&lt;LI&gt;Generic method parameters &lt;/LI&gt;
&lt;LI&gt;Arrays &lt;/LI&gt;&lt;/OL&gt;
&lt;H3&gt;Consuming Extension Methods &lt;/H3&gt;
&lt;P&gt;In order to consume an extension method, you simply need to bring it into scope. The method will then be visible in intellisence and callable as if it was an instance method. This is a rather simple statement, but it has several interesting implications. In particular, this is a distinct departure from the behavior we implemented in the May 2006 Linq CTP, where we required each type that defined extension methods to be individually imported before its extensions could be used. Although this had some advantages, such as providing fine grained control over extension method visibility, it also suffered from numerous drawbacks. &lt;/P&gt;
&lt;P&gt;One big problem was the fact that it was different than C#, which makes extension methods visible by importing the namespace that contains the types that define them. To see why this is an issue, consider the following 2 example C# class libraries:&lt;BR&gt;&lt;/P&gt;
&lt;P&gt;Example 1: &lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;namespace&lt;/SPAN&gt; CSharpExtensionMethodLibrary&lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;Extensions1&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; ExtensionMethod1(&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; x)&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; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;Extensions2&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; ExtensionMethod2(&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; x)&lt;BR&gt;&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; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;Extensions3&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; ExtensionMethod3(&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; x)&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;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;Extensions4&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; ExtensionMethod4(&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; x)&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; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;Extensions5&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; ExtensionMethod5(&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; x)&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; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;};&lt;BR&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Example 2: &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;BR&gt;namespace&lt;/SPAN&gt; CSharpExtensionMethodLibrary&lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;Extensions&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; ExtensionMethod1(&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; x)&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; }&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; ExtensionMethod2(&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; x)&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;}&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; ExtensionMethod3(&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; x)&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; }&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; ExtensionMethod4(&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; x)&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; }&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; ExtensionMethod5(&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; x)&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; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;};&lt;BR&gt;&lt;/SPAN&gt;&lt;BR&gt;Here the first example defines an extension method library with the extensions defined in several different static classes all in the same namespace. The second example defines the same extension methods concentrated into a single class. From the point of view of a C# consumer, these libraries are equivalent. To consume them, a C# program simply needs to import their containing namespace. For a VB consumer in the May 2006 Linq CTP, however, these libraries are very different. To consume the first one, a VB programmer would need to add 5 imports statements to his code, where as with the second one he would only need to add one. &lt;BR&gt;&lt;/P&gt;
&lt;P&gt;Using Example 2 from C#: &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; CSharpExtensionMethodLibrary; &lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;C1 &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;{ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; Main() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;{&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; x = &lt;SPAN style="COLOR: #a31515"&gt;""&lt;/SPAN&gt;; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;x.Extension1(); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;x.Extension2(); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;x.Extension3(); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;x.Extension4(); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;x.Extension5(); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;} &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;}&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Using Example 2 from VB in the May 2006 CTP: &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Imports&lt;/SPAN&gt; CSharpExtensionMethodLibrary.Extension1 &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Imports&lt;/SPAN&gt; CSharpExtensionMethodLibrary.Extension2 &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Imports&lt;/SPAN&gt; CSharpExtensionMethodLibrary.Extension3 &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Imports&lt;/SPAN&gt; CSharpExtensionMethodLibrary.Extension4 &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Imports&lt;/SPAN&gt; CSharpExtensionMethodLibrary.Extension5 &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Module&lt;/SPAN&gt; M1 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Main() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Dim&lt;/SPAN&gt; x &lt;SPAN style="COLOR: blue"&gt;as String&lt;/SPAN&gt; = &lt;SPAN style="COLOR: #a31515"&gt;"" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;x.Extension1() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;x.Extension2() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;x.Extension3() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;x.Extension4() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Module &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Obviously this has the potential of causing API usability problems for VB programmers consuming C# extension methods. &lt;/P&gt;
&lt;P&gt;&lt;BR&gt;However, by restricting our rules to only allow extension methods to be defined in modules and changing the rules for extension method visibility to include "any extension method in scope", we were able to solve this problem and achieve parity with C# in a way that meshed well with existing VB language concepts. This works because VB modules have the property of "hoisting" there members into their containing namespace, so importing a namespace will also bring the extension methods defined in its types into scope. Therefore, by treating C# static classes as VB modules (for the purposes of extension methods), we can ensure that VB customers have an API usability experience that is comparable to C#.&lt;BR&gt;&lt;BR&gt;Using Example2.dll from VB in Orcas:&lt;BR&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Imports&lt;/SPAN&gt; CSharpExtensionMethodLibrary &lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Module&lt;/SPAN&gt; M1 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Main() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Dim&lt;/SPAN&gt; x = &lt;SPAN style="COLOR: #a31515"&gt;"" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;x.Extension1() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;x.Extension2() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;x.Extension3() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;x.Extension4() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Module &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;However, we still retain the ability to import a module directly, so the fine grained control offered by the May 2006 CTP is available for anyone who needs it. We've also introduced shadowing rules that give you some degree of control in resolving conflicts between extension methods. More explicitly, we break extension methods into a series of precedence levels based on the mechanism used to bring them into scope. In the event of a conflict between two methods with identical signatures and different precedence levels, we will pick the one with the higher precedence level. The complete list of these levels is shown below (items with lower numbers have higher precedence). &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Extension methods defined inside the current module (if there is one) &lt;/LI&gt;
&lt;LI&gt;Extension methods defined inside types in the current namespace or any of its parents, with child namespaces having higher precedence than parent namespaces &lt;/LI&gt;
&lt;LI&gt;Extension methods defined inside any type imports in the current file &lt;/LI&gt;
&lt;LI&gt;Extension methods defined inside any namespace imports in the current file &lt;/LI&gt;
&lt;LI&gt;Extension methods defined inside any project-level type imports &lt;/LI&gt;
&lt;LI&gt;Extension methods defined inside any project-level namespace imports &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;In the event that these shadowing rules are not enough to resolve ambiguities you may always bind to a particular method by using the old Whidbey-Style shared method syntax (i.e. StringExtensions.Speak(x) as opposed to x.Speak()). &lt;/P&gt;
&lt;P&gt;I think that is enough for today. Fortunately, I've only scratched the surface. In my next several posts I will dig into some of the issues you need to be aware of when writing extension method libraries, including: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Extension methods on Value Types &lt;/LI&gt;
&lt;LI&gt;VB Late Binding and Object Extensions &lt;/LI&gt;
&lt;LI&gt;Type Inference rules for Generic Extension Methods &lt;/LI&gt;
&lt;LI&gt;Extension method Versioning Issues &lt;/LI&gt;&lt;/OL&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1452112" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/vbteam/archive/tags/LINQ_2F00_VB9/default.aspx">LINQ/VB9</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/Scott+Wisniewski/default.aspx">Scott Wisniewski</category></item><item><title>Extension methods (part 1) </title><link>http://blogs.msdn.com/vbteam/archive/2007/01/05/extension-methods-part-1.aspx</link><pubDate>Fri, 05 Jan 2007 22:59:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1417621</guid><dc:creator>VBTeam</dc:creator><slash:comments>20</slash:comments><comments>http://blogs.msdn.com/vbteam/comments/1417621.aspx</comments><wfw:commentRss>http://blogs.msdn.com/vbteam/commentrss.aspx?PostID=1417621</wfw:commentRss><description>&lt;P&gt;Hi. &lt;/P&gt;
&lt;P&gt;I'm Scott Wisniewski, a dev on the VB Compiler Team. I've been here for a while now (about a year and a half), but this is my first blog post. I've been spending the past seven months or so working on Orcas, and finally decided it would be a good time to come up for some air, talk about what I've been working on, and start to actually make a dent against my blogging commitments. &lt;/P&gt;
&lt;P&gt;I figured the best place to start is with my favorite feature: extension methods. If you didn't know this already, one of the new features we are adding to VB 9.0 is Extension Methods, which provide a very powerful and elegant way to inject your own custom functionality into other people's types. In particular, through a great deal of compiler magic, Extension methods enable you to create a method in a module decorated with an attribute and have that method appear as if it was an instance method defined on another type. Here is a simple example, where we define an extension method that adds a method called "Speak" directly to the string class. &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Imports&lt;/SPAN&gt; System.Runtime.CompilerServices &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Imports&lt;/SPAN&gt; System.Speech.Synthesis &lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Module&lt;/SPAN&gt; Module1 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;lt;Extension()&amp;gt; _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Speak(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; x &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;String&lt;/SPAN&gt;) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Using&lt;/SPAN&gt; synth &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;New&lt;/SPAN&gt; SpeechSynthesizer() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;synth.Speak(x) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Using&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Main() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Dim&lt;/SPAN&gt; x = &lt;SPAN style="COLOR: #a31515"&gt;"Hello World"&lt;/SPAN&gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;x.Speak() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Module &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;This method then wraps up the speech API, causing the string to be spoken through the computer's speakers. &lt;/P&gt;
&lt;P&gt;If we examine the method definition, it looks more or less exactly like any run-of-the-mill helper routine, with the notable exception of it being decorated with the "System.Runtime.CompilerServices.Extension" attribute. The use of this attribute instructs the compiler to treat the method as an extension method, which in turn causes the new helper method to appear as if it was a pre-defined instance method automatically available to users of the string class.&lt;BR&gt;&lt;BR&gt;If we compare this to the old way of doing things, the feature really starts to show its elegance. In Whidbey, helper routines that operated on common types(particularly non-extensible types like "string", "sealed classes", and interfaces) often suffered from a few draw backs. Mainly: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;They were not easily discoverable through intellisence &lt;/LI&gt;
&lt;LI&gt;They use an awkward, counter-intuitive syntax &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Intellisence is, in my opinion, one of the greatest programming tools ever invented. Beyond the obvious productivity gains it introduces, is the tremendous discoverability it provides. Many programmers (myself included) often find themselves dealing with objects they have either never seen before or are generally unfamiliar with. In these cases, Intellisence proves to be incredibly valuable, because it allows you to effortlessly discover how these objects work. If you want to know what data is stored in an object, or what operations it is capable of performing, you simply just need to type a "." after the object name or the operation that provided the object to you and intellisence will sweep in and provide you a nice organized picture of what the object is capable of. &lt;/P&gt;
&lt;P&gt;With custom-written shared utility methods in Whidbey, however, this kind of discoverability is not possible. Although intellisence will provide parameter info about how to call these methods, and will provide code completion if you start to type their names, it provides little in the way of help for people who do not know that these utility methods exist and are available for their consumption. In particular, calling a utility method uses a different syntax than calling an instance method (Speak("Hello World") versus "Hello World".Split()), and so while typing "." after a string will display "Split" amongst the list of possible choices, and parameter info will be provided after typing "Speak(", the user of an API has to know, ahead of time, weather the function he or she is calling is a shared utility method written by a third party or an instance method provided directly by the class author in order to get help from the compiler about how to use it. &lt;/P&gt;
&lt;P&gt;Extension methods in Orcas, however, fix this problem by merging third party utility methods with canned instance methods written by class authors, essentially making utility methods just as discoverable as the built-in ones. The screen-shot below shows an example of this in action: &lt;/P&gt;
&lt;P&gt;&lt;IMG title="Extension Methods Are Cool" style="WIDTH: 531px; HEIGHT: 347px" height=347 alt="Extension Methods Are Cool" src="http://vbteam.members.winisp.net/blog/scottwis/ExtensionMethods01.jpg" width=531 mce_src="http://vbteam.members.winisp.net/blog/scottwis/ExtensionMethods01.jpg"&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: Times New Roman"&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;A programmer in Whidbey, who may not have been aware that a helper method named "Speak" existed, would receive immediate feedback in Orcas about its existence. Personally, I think this is revolutionary. &lt;/P&gt;
&lt;P&gt;Also, instance methods have a distinct advantage over shared utility methods in that they make it much easier to chain operations together. As an example, consider a task which requires Translating a string from English to Spanish, running it through a grammar checker, and then finally sending it out as the body of an Email message. Accomplishing this using helper methods may look something like this:&lt;BR&gt;&lt;BR&gt;SendEmailToCustomer(TranslateToSpanish(RunGrammerChecker("Extension methods are cool".) ) )&lt;BR&gt;&lt;BR&gt;This has the problem, however, of being somewhat counterintuitive. The operations are specified in the opposite order in which they are executed, which makes the code both harder to write and more difficult to understand. If these helper methods were written as Extension methods, however, they could be called just like instance methods allowing users of the API to write something like this:&lt;BR&gt;&lt;BR&gt;"Extension methods are Cool".RunGrammarChecker().TranslateToSpanish().EmailToCustomer() &lt;/P&gt;
&lt;P&gt;This is easier to write, because intellisence provides better completion lists, and easier to read because the operations are specified in the same order they execute. &lt;/P&gt;
&lt;P&gt;In any case, I hope this is enough to wet your appetite for the coolness of extension methods. In my next post, I'll dig a bit more into the details of how they work, the rules for defining them, and how they are used. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1417621" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/vbteam/archive/tags/LINQ_2F00_VB9/default.aspx">LINQ/VB9</category><category domain="http://blogs.msdn.com/vbteam/archive/tags/Scott+Wisniewski/default.aspx">Scott Wisniewski</category></item></channel></rss>