<?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>There and Back Again : Visual Studio 2008</title><link>http://blogs.msdn.com/howard_dierking/archive/tags/Visual+Studio+2008/default.aspx</link><description>Tags: Visual Studio 2008</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Building NHibernate 1.2.1GA on .NET 3.5</title><link>http://blogs.msdn.com/howard_dierking/archive/2008/03/20/building-nhibernate-1-2-1ga-on-net-3-5.aspx</link><pubDate>Fri, 21 Mar 2008 00:49:14 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8327970</guid><dc:creator>hdierking</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/howard_dierking/comments/8327970.aspx</comments><wfw:commentRss>http://blogs.msdn.com/howard_dierking/commentrss.aspx?PostID=8327970</wfw:commentRss><description>&lt;p&gt;I recently reached a point where for reasons that I'm sure you can all relate to, I decided to clean my laptop and rebuild.&amp;#160; I therefore did a clean install of Vista with SP1.&amp;#160; As a quick aside, SP1 does actually seem to improve performance - particularly when starting up or closing down.&amp;#160; Anyway, after I was back up and going again, I setup &lt;a href="http://nant.sourceforge.net/"&gt;NAnt&lt;/a&gt; and then downloaded the &lt;a href="http://www.hibernate.org/343.html"&gt;NHibernate&lt;/a&gt; 1.2.1 GA source.&amp;#160; However, I ran into 2 major problems building, so I thought I would share those, along with how to work around them.&lt;/p&gt;  &lt;p&gt;Both problems can be corrected by modifying the markup in the build-common/common.xml file.&lt;/p&gt;  &lt;p&gt;The first problem had to do with the fact that the build was expecting the clover library.&amp;#160; The solution was simply to add a condition to the property set declaration.&amp;#160; I'm not going to spend any more time on this one, because the problem/solution is &lt;a href="http://forum.hibernate.org/viewtopic.php?p=2373051"&gt;documented here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The second problem is that there is no target in the build file for .NET 3.5.&amp;#160; On most machines, this isn't a big deal because you've probably upgraded framework versions incrementally, and the build file can target 2.0 with no problem.&amp;#160; Because I have a fresh OS/Framework install, I got an error saying that .NET 3.5 is not supported for my build of NHibernate.&amp;#160; This can be worked around by adding a target declaring a configuration for .NET 3.5, like so:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;target &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;set-net-3.5-framework-configuration&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;property &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;nant.settings.currentframework&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;net-2.0&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;property &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;current.build.defines&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;${build.defines}NET,NET_2_0&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;!-- &lt;/span&gt;&lt;span style="color: green"&gt;not using SDK_v2_0 because ndoc throws an exception &lt;/span&gt;&lt;span style="color: blue"&gt;--&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;property &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;link.sdkdoc.version&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;SDK_v1_1&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;property &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;merge.targetplatform&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;v2.0&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;target&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;When you get into the config file, you'll see that all I did was create a target with 3.5 declared as a part of the target name, and then coped the body from the 2.0 target inside of my 3.5 target.&amp;#160; Initially, I had actually configured the properties to make them specific to .NET 3.5.&amp;#160; Unfortunately, I later discovered when I tried to use the compiled assemblies that many of the source files have preprocessing directives that are specific to the defines declared in the build properties.&amp;#160; For example, the ISet&amp;lt;T&amp;gt; source code is wrapped with the following directive.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;#if &lt;/span&gt;NET_2_0&lt;/pre&gt;

&lt;p&gt;Anways, after making these 2 changes, I was able to build with no problem, and NHibernate continued to work as advertised.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8327970" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Microsoft+.NET+Programming/default.aspx">Microsoft .NET Programming</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/My+Toolbox/default.aspx">My Toolbox</category></item><item><title>Wow - That Was Annoying</title><link>http://blogs.msdn.com/howard_dierking/archive/2007/11/18/wow-that-was-annoying.aspx</link><pubDate>Mon, 19 Nov 2007 05:18:53 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6385661</guid><dc:creator>hdierking</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/howard_dierking/comments/6385661.aspx</comments><wfw:commentRss>http://blogs.msdn.com/howard_dierking/commentrss.aspx?PostID=6385661</wfw:commentRss><description>&lt;p&gt;So I'm in an awkward place right now when it comes to programming.&amp;#xA0; In addition to the fact that I no longer program on a day-to-day basis (which is starting to bug me a little more than it used to as I'm afraid I'm starting to atrophy a bit), I'm also now up on Visual Studio 2008 - which is really great in a lot of respects - but at the same time is kind of bumming me out.&amp;#xA0; I'm not bummed because of anything inherent in Visual Studio - I'm bummed because Resharper just doesn't really work all that great in it.&amp;#xA0; Don't get me wrong - R# works - but the semantic analysis tools don't yet work with a lot of the C# 3.0 language enhancements - and as much as I tried to ignore the R# compiler errors on things like Linq queries, I finally just got tired of it an uninstalled R#, impatiently awaiting the 4.0 release.&lt;/p&gt;  &lt;p&gt;Firstly, let me just say that not having R# is miserable from a refactoring standpoint.&lt;/p&gt;  &lt;p&gt;Secondly, losing R# led me down the path to another headache (which is the subject of this post) - I no longer have a VS add-in runner for NUnit.&amp;#xA0; Yes, I know - I could (and probably should) go back and download TD.NET - but instead, I was curious to see how easily it would be for me to just convert my NUnit tests to VS 2008 unit tests.&amp;#xA0; In short, it's not terribly difficult, but getting there was a frustrating journey.&lt;/p&gt;  &lt;p&gt;Why?&amp;#xA0; Because unlike NUnit, where a test fixture is explicit in code (and only in code) via the TestFixture attribute, VS tests rely on a second piece of metadata in order to have them run via the VS test manager/test runner.&amp;#xA0; That metadata is not found in the *.vsmdi file - instead, it's actually a property in the project file of your unit test project.&lt;/p&gt;  &lt;p&gt;Therefore, if you started from a regular class library project and need to have it recognized by VS as a &amp;quot;test project&amp;quot;, open the *.csproj file in notepad and add the following to any PropertyGroup.&lt;/p&gt;  &lt;p&gt;&amp;lt;ProjectTypeGuids&amp;gt;{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}&amp;lt;/ProjectTypeGuids&amp;gt;&lt;/p&gt;  &lt;p&gt;The first Guid identifies your project as a test project (the second is the language I believe - feel free to correct me if I'm wrong).&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6385661" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Microsoft+.NET+Programming/default.aspx">Microsoft .NET Programming</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Test+Driven+Development/default.aspx">Test Driven Development</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Agile/default.aspx">Agile</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/My+Toolbox/default.aspx">My Toolbox</category></item><item><title>Linq-i-fying My Existing Projects - Part 1</title><link>http://blogs.msdn.com/howard_dierking/archive/2007/11/14/linq-i-fying-my-existing-projects-part-1.aspx</link><pubDate>Wed, 14 Nov 2007 19:09:39 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6215100</guid><dc:creator>hdierking</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/howard_dierking/comments/6215100.aspx</comments><wfw:commentRss>http://blogs.msdn.com/howard_dierking/commentrss.aspx?PostID=6215100</wfw:commentRss><description>&lt;p&gt;To be honest, I don't know how many parts there will end up being - since the longer I'm away from day to day developing, the fewer projects I have to go back through.&amp;#xA0; However, I can think of a few more off the top of my head - so I still think that &amp;quot;Part n&amp;quot; is a fair statement.&lt;/p&gt;  &lt;p&gt;Anyway, for a sample golfing application, I have the following hierarchy (fragment).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/howard_dierking/WindowsLiveWriter/LinqifyingMyExistingProjectsPart1_7265/image_4.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="142" alt="image" src="http://blogs.msdn.com/blogfiles/howard_dierking/WindowsLiveWriter/LinqifyingMyExistingProjectsPart1_7265/image_thumb_1.png" width="405" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Now, ignoring for the moment the fact that I didn't make Round a generic and thereby avoid the need for it, the following method in Round validates that either Players or Teams can play a round of golf, but not a mixture of both (e.g. - a single player cannot go up against a team).&lt;/p&gt;  &lt;div&gt;private void ValidatePlayerTypeConsistency(Player[] players) { &lt;/div&gt;  &lt;div&gt;&amp;#xA0; foreach (Player player in players) { &lt;/div&gt;  &lt;div&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0; if (!player.GetType().Equals(_expectedPlayerType)) &lt;/div&gt;  &lt;div&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; throw new ArgumentException(&amp;quot;Player was not of the expected type ('&amp;quot; + &lt;/div&gt;  &lt;div&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; _expectedPlayerType.FullName + &amp;quot;')&amp;quot;); &lt;/div&gt;  &lt;div&gt;&amp;#xA0; } &lt;/div&gt;  &lt;div&gt;}&lt;/div&gt;  &lt;p&gt;Using a C# 3.0 Linq query, the imperative structure of the foreach loop can now be replaced with a more declarative one as follows.&lt;/p&gt;  &lt;div&gt;private void ValidatePlayerTypeConsistency(Player[] players) { &lt;/div&gt;  &lt;div&gt;&amp;#xA0; bool hasUnexpectedPlayers = (from p in players select p)&lt;/div&gt;  &lt;div&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0; .Any(p =&amp;gt; !p.GetType().Equals(_expectedPlayerType)); &lt;/div&gt;  &lt;div&gt;&amp;#xA0;&lt;/div&gt;  &lt;div&gt;if(hasUnexpectedPlayers) &lt;/div&gt;  &lt;div&gt;&amp;#xA0; throw new ArgumentException(&amp;quot;Player was not of the expected type ('&amp;quot; + &lt;/div&gt;  &lt;div&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0; _expectedPlayerType.FullName + &amp;quot;')&amp;quot;); &lt;/div&gt;  &lt;div&gt;}&lt;/div&gt;  &lt;p&gt;A couple of quick things to notice here:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;In the Linq query, the C# 3.0 language extensions do not cover the entire breadth of Linq functionality (e.g. - the &amp;quot;Any&amp;quot; quantifier).&amp;#xA0; When you run into cases like this, remember that it is perfectly acceptable to mix the language extensions syntax with the standard extension method/lambda syntax.&amp;#xA0; You can do this by simply enclosing the language extensions syntax block in parentheses and then calling additional methods on the result. &lt;/li&gt;    &lt;li&gt;My Linq query syntax didn't really reduce my total line count and the declarative syntax is arguably harder to read.&amp;#xA0; To this, I can only say a) this is a really simple example and b) like anonymous delegates and generics, you get used to it.&amp;#xA0; That said, this example should illustrate that you should take a pragmatic approach to incorporating new features like Linq into your applications. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;A final note here - I am ONLY able to do this type of code replacement because I have a great set of unit tests backing me up.&amp;#xA0; In fact, when I first tried out the Linq approach, my test failed.&amp;#xA0; DO NOT make changes like this to working applications without having good tests to back you up.&lt;/p&gt;  &lt;p&gt;Hopefully, I'll bring you some more complex examples soon.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6215100" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Microsoft+.NET+Programming/default.aspx">Microsoft .NET Programming</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Test+Driven+Development/default.aspx">Test Driven Development</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/LINQ/default.aspx">LINQ</category></item><item><title>ALT.NET Conference, Day 2 - Taking the Good With the Bad</title><link>http://blogs.msdn.com/howard_dierking/archive/2007/10/06/alt-net-conference-day-2-taking-the-good-with-the-bad.aspx</link><pubDate>Sun, 07 Oct 2007 07:57:27 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5331457</guid><dc:creator>hdierking</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/howard_dierking/comments/5331457.aspx</comments><wfw:commentRss>http://blogs.msdn.com/howard_dierking/commentrss.aspx?PostID=5331457</wfw:commentRss><description>&lt;p&gt;Today's post is actually a nice continuance of yesterday's because it deals very specifically with one of the issues that I raised yesterday - specifically the issue of the emerging tenuous relationship between the ALT.NET community and the rest of the professional .NET developer community.&amp;nbsp; That said, today was fantastic - great people, great discussions - and a great show of forthcoming technology by &lt;a href="http://weblogs.asp.net/scottgu/default.aspx"&gt;ScottGu&lt;/a&gt;.&amp;nbsp; So, in sum, we'll deal with the good and the not so good in tonight's post (IMHO &amp;lt;g&amp;gt;)!&lt;/p&gt; &lt;h4&gt;The Not So Good - How to Be a Catalyst for Change In the Community&lt;/h4&gt; &lt;p&gt;I went into this session hoping that individuals would come in wanting to share success and/or failure stories related to creating an environment that bought into at least some of the principles of agile - or at the very least became more passionate about writing great software.&amp;nbsp; I also went in expecting there to be a fair amount of Microsoft bashing because of designers, code generation, NIH, etc... (I would mention MSDN/&lt;a href="http://msdn.microsoft.com/msdnmag/"&gt;MSDN Magazine&lt;/a&gt; here, but that session is tomorrow, so I'll deal with that in the morning).&amp;nbsp; What actually unfolded actually surprised me a bit.&amp;nbsp; So firstly, I should say that there were some success stories shared.&amp;nbsp; &lt;a href="http://www.jpboodhoo.com/blog/"&gt;J.P. Boodhoo&lt;/a&gt; talked about some of the successes he has had with "lunch &amp;amp; learns" - &lt;a href="http://www.hanselman.com/blog/"&gt;Scott Hanselman&lt;/a&gt; and &lt;a href="http://jayflowers.com/joomla/"&gt;Jay Flowers&lt;/a&gt; talked about growing influence exponentially via a style that for this post we'll call "influencing the influencers" (Jay - you had mentioned a book that dealt with this topic - if you're reading, please post the title in the comments).&amp;nbsp; Past those (and a few other) examples, though, the conversation took what I considered a fairly cynical and elitist turn.&amp;nbsp; Earlier I mentioned that I was surprised a bit by what unfolded.&amp;nbsp; What surprised me was that the frustration expressed was not as much directed at Microsoft, but was directed at the general development community.&amp;nbsp; It basically came across as "why won't all these people stop calling me dogmatic and listen to what I'm trying to tell them?!?"&amp;nbsp; Several in the room made the argument that energy should only be expended on influencing those who wanted to be influenced.&amp;nbsp; Huh??&amp;nbsp; If they...want to be influenced....doesn't that already....nevermind.&amp;nbsp; Anyway, I basically came away from that session with 2 concluding saddening thoughts about many in the ALT.NET community.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;They will always be 10 steps ahead of the rest of the professional development community because they are incredibly smart, talented, and motivated.&lt;/li&gt; &lt;li&gt;They will always be frustrated because they are narcissistic.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;OK - maybe it was because I drank more coffee, maybe it was something else, but the day got much better as it progressed.&amp;nbsp; Let's move on.&lt;/p&gt; &lt;h4&gt;The Good - DSLs/NHibernate&lt;/h4&gt; &lt;p&gt;I'm grouping these together because I walked in half way through the &lt;a href="http://en.wikipedia.org/wiki/Domain-specific_programming_language"&gt;DSL&lt;/a&gt; talk and I just didn't take that many notes from the &lt;a href="http://www.hibernate.org/343.html"&gt;NHibernate&lt;/a&gt; talk.&amp;nbsp; In fact, I think I'm just going to do bullet points here.&lt;/p&gt; &lt;h5&gt;DSL&lt;/h5&gt; &lt;ul&gt; &lt;li&gt;I hadn't realized that Microsoft &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/10/03/releasing-the-source-code-for-the-net-framework-libraries.aspx"&gt;released the source code for the .NET Framework Class Library&lt;/a&gt;.&amp;nbsp; Totally cool - especially since, as ScottGu mentioned, they shipped it with the symbols, so profiling and debugging into the framework itself is now simple.&lt;/li&gt; &lt;li&gt;There was a lot of talk about DSL support in Ruby.&amp;nbsp; I haven't worked in Ruby so I really can't speak to this - but now I'm curious.&lt;/li&gt; &lt;li&gt;One really interesting comment that ScottGu made, regarding DSLs is to make sure that you have mastered your GPL first, as this will provide you the best platform from which to jump into DSLs.&lt;/li&gt;&lt;/ul&gt; &lt;h5&gt;NHibernate&lt;/h5&gt; &lt;ul&gt; &lt;li&gt;It was tough to blur the lines between where we crossed into a general &lt;a href="http://www.domaindrivendesign.org/"&gt;DDD&lt;/a&gt; discussion and when we were still talking about NHibernate - particularly when we were discussing architectural patterns for DALs, etc...&lt;/li&gt; &lt;li&gt;To the NHibernate team (or someone with the time to look at this on the forge) - It would be totally cool if we could get JIT loading of HBMs, or at least have the option to suppress fail-fast when building the session factory.&amp;nbsp; This came out of a discussion where many in the group were expressing the pain felt when one invalid HBM file caused every unit test to fail (or nearly every view to crash) because the session factory couldn't be created.&lt;/li&gt; &lt;li&gt;On that note, a MSBuild/NAnt HBM validator build task would be nice for plugging into the build.&lt;/li&gt;&lt;/ul&gt; &lt;h4&gt;The Rockin' - ScottGu's Show and Tell&lt;/h4&gt; &lt;p&gt;So I haven't really had a lot of exposure to MVC in web applications (yes, I have let the whole RoR phenomenon pass me by - for shame, I know).&amp;nbsp; And as a result, I really didn't see the point of the whole paradigm shift to MVC.&amp;nbsp; I did DVC in MFC and it was a pain - so perhaps I was just avoiding the topic because of past aches, but for whatever reason, this was all new to me.&amp;nbsp; So anyways, Scott demonstrated the new MVC framework that will be available in CTP form pretty soon.&amp;nbsp; Honestly, it's pretty cool.&amp;nbsp; I don't really buy into the argument that MVC is absolutely necessary to cleanly separate the logical layers of your application.&amp;nbsp; I have been doing DDD for a while now and have never run into a major problem with bleeding of concerns on web projects - but maybe that's just me.&amp;nbsp; However, if you're into having leaner, better controlled HTML and, more intuitive URLs, and reduced &lt;em&gt;probability&lt;/em&gt; for concern-bleed, the MVC framework is definitely the way to go.&lt;/p&gt; &lt;p&gt;On a related note, let the record show that &lt;a href="http://codebetter.com/blogs/scott.bellware/"&gt;Scott Bellware&lt;/a&gt; is officially my favorite heckler.&amp;nbsp; Scott - whenever you're in Redmond, the drinks are on me!&lt;/p&gt; &lt;p&gt;Back to the MVC discussion, my main next action is to see if I can actually find the bits so that I can get up to speed a bit.&amp;nbsp; Who knows, maybe I'll even take the approach of one of my close friends at P&amp;amp;P and buy a Macbook Pro to play with RoR &amp;lt;g&amp;gt;!&lt;/p&gt; &lt;h4&gt;The Confused - DDD&lt;/h4&gt; &lt;p&gt;So since this post is getting long, I'm going to sum this session up with a pretty simple statement.&amp;nbsp; &lt;strong&gt;&lt;a href="http://www.domaindrivendesign.org/about/index.html#eric"&gt;Eric&lt;/a&gt; - A little help please? &lt;/strong&gt; There continues to be a great deal of confusion and disagreement in the DDD community about some very fundamental concepts.&amp;nbsp; Examples include the definition of a domain service, an application service, and the very distinctive characterics of DDD that make it different than simply good OOP heuristics.&lt;/p&gt; &lt;p&gt;On a closing note, I have never seen so many iPhones in one place.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5331457" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Agile/default.aspx">Agile</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/MSDN+Magazine/default.aspx">MSDN Magazine</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Events/default.aspx">Events</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/ALTNETCONF/default.aspx">ALTNETCONF</category></item><item><title>So Mad Right Now</title><link>http://blogs.msdn.com/howard_dierking/archive/2007/10/03/so-mad-right-now.aspx</link><pubDate>Thu, 04 Oct 2007 05:24:38 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5270261</guid><dc:creator>hdierking</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/howard_dierking/comments/5270261.aspx</comments><wfw:commentRss>http://blogs.msdn.com/howard_dierking/commentrss.aspx?PostID=5270261</wfw:commentRss><description>&lt;p&gt;All I want to do is install VS 2008 - that's all.&amp;nbsp; Unfortunately, the uninstall story with VS 2005 is so complicated that in the process of individually uninstalling the 10+ different applications (according to MSI), I have somehow also corrupted my LifeCam software, so now I'm unable to webcam with my wife and new baby while traveling.&lt;/p&gt; &lt;p&gt;Maybe I had never noticed before because I was a full-time developer and I was in a constant state of reformatting my machine anyway, but seriously - is formatting the only viable option for installing Visual Studio?&lt;/p&gt; &lt;p&gt;At the moment, it certainly seems that way...&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5270261" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Visual+Studio+Team+System/default.aspx">Visual Studio Team System</category></item><item><title>OBA - Are We There Yet?</title><link>http://blogs.msdn.com/howard_dierking/archive/2007/08/25/oba-are-we-there-yet.aspx</link><pubDate>Sun, 26 Aug 2007 08:40:04 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4570083</guid><dc:creator>hdierking</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/howard_dierking/comments/4570083.aspx</comments><wfw:commentRss>http://blogs.msdn.com/howard_dierking/commentrss.aspx?PostID=4570083</wfw:commentRss><description>&lt;p&gt;I am a beliver in the power of Office as the pre-eminant smart client for the majority of LOB applicaitons.&amp;nbsp; However, I also think that we're still a little ways off from realizing my belief - not because of some entrenched &lt;a href="http://en.wikipedia.org/wiki/Not_invented_here"&gt;NIH complex&lt;/a&gt; held to by consultants (though there is some of that (NOTE: because I was a consultant for at least half of my career, I take the liberty of making such broad generalizations in good fun &amp;lt;g&amp;gt;)). - but because in general, both the tooling and the guidance for building business apps based on Office as a platform has been somewhere between sketchy and non-existant.&lt;/p&gt; &lt;p&gt;Office 2007 brought us closer with the adoption of the OpenXML document formats - and with the forthcoming VSTO enhancements, like click once support for customizations, we take another step.&amp;nbsp; Also, today I stumbled upon &lt;a href="http://msdn2.microsoft.com/en-us/office/bb497969.aspx"&gt;this piece of guidance for developers&lt;/a&gt; - I'm not sure that it's necessarily guidance, but it certainly at least lays out the different options (and it just looks cool).&lt;/p&gt; &lt;p&gt;So while we're not yet past having to deal with COM and all of its associated headaches, we can at least have a pretty WPF applet to play with.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4570083" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Microsoft+.NET+Programming/default.aspx">Microsoft .NET Programming</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Microsoft+Office+2007+Programming/default.aspx">Microsoft Office 2007 Programming</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Learning+Resources/default.aspx">Learning Resources</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/SharePoint/default.aspx">SharePoint</category></item><item><title>C# 3.0 Object Initializers</title><link>http://blogs.msdn.com/howard_dierking/archive/2007/08/13/c-3-0-object-initializers.aspx</link><pubDate>Mon, 13 Aug 2007 18:59:38 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4369372</guid><dc:creator>hdierking</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/howard_dierking/comments/4369372.aspx</comments><wfw:commentRss>http://blogs.msdn.com/howard_dierking/commentrss.aspx?PostID=4369372</wfw:commentRss><description>&lt;p&gt;As I'm sure you are aware, C# 3.0 includes a new language feature called object initializers.&amp;nbsp; Put simply, object initializers enable you to initialize the state of an object with a single expression that does not require use of parameterized constructors.&amp;nbsp; A few million examples on the object initializer syntax ranging from the simple to complex are out there on the Internet, so there's no need for me to go into them here.&amp;nbsp; I do, however, want to make a couple of quick points.&lt;/p&gt; &lt;p&gt;1.&amp;nbsp; The object initializer syntax sits on top of the standard C# language - and it does not allow you to break the basic OO rules of the language.&amp;nbsp; It feels to me like many of the language features coming down the pipe (at least for both C# 2 and 3) have their real value when taken in groups.&amp;nbsp; For example, while a cool feature, anonymous methods didn't shine quite so brightly until used in conjunction with generic delegates and the type inference capabilities of C# 2.0 (obviously, lambda expressions are the latest incarnation of this capability).&amp;nbsp; Similarly, object Initializers seem to have their most value when used in conjunction with anonymous types - and more specifically, when used with anonymous types in the context of a LINQ projection operation.&lt;/p&gt; &lt;p&gt;That said, object initializers should not be thought of as a way to side-step basic object heuristics (and from the implementation perspective, the C# compiler won't let you).&amp;nbsp; For example, a basic tenant of OO design specifies that an object should be ready to use&amp;nbsp;after constructed.&amp;nbsp; As a result, many classes are designed such that there are no parameterless constructors (since the result would yield a class that still required initialization after the object was constructed).&amp;nbsp; In this case, you must call a parameterized constructor even when using the object initializer syntax.&amp;nbsp; It is worth pointing out, however, that the object initializer syntax is quite handy here in eliminating a lot of "shortcut constructors" from the code base.&amp;nbsp; The constructor code can require only the parameters that are absolutely necessary to construct the object, while the object initializer syntax can be relied on for allowing the user to provide additional state to the constructed object.&lt;/p&gt; &lt;p&gt;Just in case you hadn't heard yet, this new language feature (and all of the other C# 3.0 features) were implemented without requiring any changes to the IL.&amp;nbsp; Let's take a look, then,&amp;nbsp;at an example of the syntax and the code generated by the compiler.&lt;/p&gt; &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;Customer jenn = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Customer(&lt;span style="color: #006080"&gt;"default"&lt;/span&gt;,0) { Name = &lt;span style="color: #006080"&gt;"jennifer"&lt;/span&gt;, Age = 31 };&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When the project is built and the assembly is reverse engineered, we can see that the generated code is as follows.&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[] args)
{
    Customer &amp;lt;&amp;gt;g__initLocal0 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Customer(&lt;span style="color: #006080"&gt;"default"&lt;/span&gt;, 0);
    &amp;lt;&amp;gt;g__initLocal0.Name = &lt;span style="color: #006080"&gt;"jennifer"&lt;/span&gt;;
    &amp;lt;&amp;gt;g__initLocal0.Age = 0x1f;
    Customer jenn = &amp;lt;&amp;gt;g__initLocal0;
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can see here that our parameterized constructor was called as it has always been, the constructed object is assigned to a temporary variable, our additional properties specified in the initializer syntax are set, and the reference held by our temporary variable is then assigned to our declared variable.&amp;nbsp; Pretty straightforward.&lt;/p&gt;
&lt;p&gt;2.&amp;nbsp; Be cautious of using object initializers with value types.&amp;nbsp; I have a real love-hate feeling for language features like this.&amp;nbsp; On the one hand, they can make life easier and code cleaner.&amp;nbsp; On the other hand, they can create a false sense of security if one assumes that the feature behaves the same in all contexts.&amp;nbsp; Take another look at the generated code.&amp;nbsp; For reference types, this is absolutely no big deal.&amp;nbsp; A managed reference has a tiny footprint, and hey - what's one more reference for the GC to track &amp;lt;g&amp;gt;?&amp;nbsp; &lt;/p&gt;
&lt;p&gt;For value types, the story is a little different.&amp;nbsp; Because you have 2 different variables, this single object initialization will end up consuming at least twice the memory required by the type itself.&amp;nbsp; In the code shown, this is probably not a big deal.&amp;nbsp; However, if your value type is a little bigger, and if you're initializing it a few hundred&amp;nbsp;times in a loop, you can see how you could inadvertently increase the footprint of your code.&amp;nbsp; For the DDD crowd, this is definitely something to be cognizant of - especially if you are using value types to implement value-objects.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4369372" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Microsoft+.NET+Programming/default.aspx">Microsoft .NET Programming</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category></item><item><title>Running Vista in VPC 2007</title><link>http://blogs.msdn.com/howard_dierking/archive/2007/08/03/running-vista-in-vpc-2007.aspx</link><pubDate>Sat, 04 Aug 2007 02:10:37 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4213629</guid><dc:creator>hdierking</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/howard_dierking/comments/4213629.aspx</comments><wfw:commentRss>http://blogs.msdn.com/howard_dierking/commentrss.aspx?PostID=4213629</wfw:commentRss><description>&lt;p&gt;I have my Orcas test bench environment setup in VPC 2007 using a Vista base image as the foundation for my Orcas differencing drive.&amp;nbsp; That said, it has been driving me absolutely crazy how slow Vista performs under VPC - so after a quick search, I came across &lt;a href="http://blogs.msdn.com/virtual_pc_guy/archive/2006/03/20/555917.aspx"&gt;this post&lt;/a&gt; from a while back by Ben Armstrong.&amp;nbsp; Just doing step 3 did wonders for me.&amp;nbsp; Vista now performs at level that's more than acceptable for me (by acceptable, I mean that the performance is such that it doesn't compete with Orcas for my attention).&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4213629" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Vista/default.aspx">Vista</category></item><item><title>DinnerNow v1.3 Is Released</title><link>http://blogs.msdn.com/howard_dierking/archive/2007/06/03/dinner-now-v1-3-is-released.aspx</link><pubDate>Mon, 04 Jun 2007 06:14:33 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:3071894</guid><dc:creator>hdierking</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/howard_dierking/comments/3071894.aspx</comments><wfw:commentRss>http://blogs.msdn.com/howard_dierking/commentrss.aspx?PostID=3071894</wfw:commentRss><description>&lt;p&gt;If you're looking for a good sample that shows how to apply some of the new .NET 3.0 technologies, check out the latest distribution of the DinnerNow.Net sample application.&amp;nbsp; &lt;a href="http://staff.southworks.net/blogs/johnny/archive/2007/06/04/DinnerNow-reloaded_2100_.aspx"&gt;More information here&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3071894" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Microsoft+.NET+Programming/default.aspx">Microsoft .NET Programming</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Architecture/default.aspx">Architecture</category></item><item><title>WF Custom Actions - Location Matters!</title><link>http://blogs.msdn.com/howard_dierking/archive/2007/05/28/wf-custom-actions-location-matters.aspx</link><pubDate>Tue, 29 May 2007 03:47:50 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2956037</guid><dc:creator>hdierking</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/howard_dierking/comments/2956037.aspx</comments><wfw:commentRss>http://blogs.msdn.com/howard_dierking/commentrss.aspx?PostID=2956037</wfw:commentRss><description>&lt;p&gt;Firstly, many thanks to &lt;a href="http://blogs.msdn.com/kavitak/"&gt;Kavita Kamani&lt;/a&gt; for helping me figure this one out.&lt;/p&gt; &lt;p&gt;As you may or may not know, &lt;a href="http://msdn2.microsoft.com/en-us/netframework/aa663328.aspx"&gt;Windows Workflow Foundation&lt;/a&gt; contains a lightweight, forward-chaining rules engine (by lightweight, I mean to say non-&lt;a href="http://en.wikipedia.org/wiki/Rete_algorithm"&gt;Rete&lt;/a&gt;).&amp;nbsp; In WF rules, a rule is defined by a condition, a collection of "then" actions, and a collection of "else" actions.&amp;nbsp; One of the really cool things about the way that the rules engine is structured is that it allows you to create your own custom actions.&amp;nbsp; Why would you want to do this?&amp;nbsp; Quite simply, because within a custom action, you have access to both the validation context and the execution context.&amp;nbsp; Therefore, custom actions in effect provide a means for extending the rules language.&lt;/p&gt; &lt;p&gt;There's only one gotcha to look out for when creating custom actions (there might be more, but here's the one that bit me).&amp;nbsp; If you create the action within the same project that contains the workflow using the action, you will get the following error when you try to call it from within the rules editor.&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/howard_dierking/WindowsLiveWriter/WFCustomActionsLocationMatters_F9DF/WFActionsError%5B3%5D.png" atomicselection="true"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="169" src="http://blogs.msdn.com/blogfiles/howard_dierking/WindowsLiveWriter/WFCustomActionsLocationMatters_F9DF/WFActionsError_thumb%5B1%5D.png" width="424" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;After beating my head against a wall for a while trying to figure out the problem, I realized that if I moved my custom action to another project and referenced it from the project that contained my workflow, everything worked just fine.&amp;nbsp; Kavita confirmed this behavior and explained that the WF Rule Editor uses CLR types rather than design-time types.&amp;nbsp; As such, as far as the rules editor is concerned, my custom action doesn't exist so long as it is in the same project.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2956037" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Microsoft+.NET+Programming/default.aspx">Microsoft .NET Programming</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Vista/default.aspx">Vista</category></item><item><title>Partial Methods - I Object?</title><link>http://blogs.msdn.com/howard_dierking/archive/2007/05/27/partial-methods-i-object.aspx</link><pubDate>Mon, 28 May 2007 07:48:28 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2934166</guid><dc:creator>hdierking</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/howard_dierking/comments/2934166.aspx</comments><wfw:commentRss>http://blogs.msdn.com/howard_dierking/commentrss.aspx?PostID=2934166</wfw:commentRss><description>&lt;p&gt;No, not partial classes.&amp;nbsp; Partial methods.&amp;nbsp; As &lt;a href="http://blogs.msdn.com/wesdyer/"&gt;Wes&lt;/a&gt; talks about in &lt;a href="http://blogs.msdn.com/wesdyer/archive/2007/05/23/in-case-you-haven-t-heard.aspx"&gt;his latest&lt;/a&gt; post on language enhancements in Orcas, partial methods are another new C# language feature that allows you to define the signature of a method in one part of a partial class&amp;nbsp;and the method implementation in another part.&amp;nbsp; For example, consider the basic entity class "SomeEntity".&lt;/p&gt; &lt;div&gt; &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; SomeEntity&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; _someAttribute;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; SomeAttribute&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;         get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _someAttribute; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;         set {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;             Validate(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;, &lt;span style="color: #006080"&gt;"SomeAttribute"&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;             OnSetting(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;, &lt;span style="color: #006080"&gt;"SomeAttribute"&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;             _someAttribute = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;             OnSet(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;, &lt;span style="color: #006080"&gt;"SomeAttribute"&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt;         }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  16:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnSet(SomeEntity someEntity, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; p);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  17:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  18:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnSetting(SomeEntity someEntity, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; p, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  19:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  20:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; Validate(SomeEntity someEntity, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; p, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  21:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On cursory inspection, this class appears like any regular entity-style class.&amp;nbsp; However, check out lines 16, 18 and 20.&amp;nbsp;&amp;nbsp;What we see here&amp;nbsp;is a method signature prototype - much like what we would see&amp;nbsp;in an&amp;nbsp;abstract base class.&amp;nbsp; However, rather than using the abstract&amp;nbsp;mechanism to facilitate extension, we are using a new keyword (well, new in this context anyway), "partial", to describe&amp;nbsp;our extension mechanism.&amp;nbsp; In order to extend any one of the&amp;nbsp;3&amp;nbsp;methods declared as partial, a developer simply creates another&amp;nbsp;part of the partial class and&amp;nbsp;implements&amp;nbsp;a method using the partial keyword and the same method name.&amp;nbsp; I'm hesitant to make any assertions about constraints on the signature as I have yet to get&amp;nbsp;the Orcas beta 2 bits and&amp;nbsp;do more&amp;nbsp;detailed testing.&amp;nbsp; However, if I read&amp;nbsp;Wes' blog correctly, I think that there may be some&amp;nbsp;room for parameter redefinition.&lt;/p&gt;
&lt;div&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; SomeEntity&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnSet(SomeEntity someEntity, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; p){&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;         &lt;span style="color: #008000"&gt;//log that the property was successfully set&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;     } &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;So, after this very basic example, the obvious question - why?&amp;nbsp; I've heard a lot of answers to this question.&amp;nbsp; However, the one rising to the top is that partial methods were added in order to provide performance optimization to code generators - most notably, Linq to SQL and Linq to DataSet.&amp;nbsp; I've also heard partial methods described as a way of doing compile-time &lt;a href="http://en.wikipedia.org/wiki/Aspect_oriented_programming"&gt;aspect weaving&lt;/a&gt;, but let's deal with the performance optimization characteristics in this post.&lt;/p&gt;
&lt;p&gt;Wes has described the primary purpose of partial methods as a way to do lightweight event handling.&amp;nbsp; I am really hesitant to use the phrase "event handling" as I think that partial methods are more of an alternative to virtual method calls than they really are to events.&amp;nbsp; Therefore, I'm going to go out on a limb and say that partial methods are a more lightweight means of composing functionality at the method level.&amp;nbsp; For you patterns folks, it is a performance optimization around the &lt;a href="http://www.dofactory.com/Patterns/PatternTemplate.aspx"&gt;template pattern&lt;/a&gt;.&amp;nbsp; How is it optimized?&amp;nbsp; Because in the current world, where the pattern is implemented through virtual methods, the compiler calls a virtual method&amp;nbsp;regardless of whether or not that method has been extended in a derrived class.&amp;nbsp; In the world of partial methods, the compiler checks to see whether the partial method being called has a concrete implementation defined and, if it does not, the compiler does not generate a call to that method.&amp;nbsp; Therefore, given our 2 examples above, if we reverse-engineered our compiled assembly, we would see that the set accessor for the SomeAttribute property looked like the following.&lt;/p&gt;
&lt;div&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; SomeAttribute&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _someAttribute; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;     set {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;         _someAttribute = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;         OnSet(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;, &lt;span style="color: #006080"&gt;"SomeAttribute"&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;So my general thinking on this is actually very similar to my general thinking on extension methods.&amp;nbsp; It seems to me like both were added as general language features, but added to support a very specific use case - Linq.&amp;nbsp; Now, that doesn't mean that I'm suggesting that they have no uses outside of Linq.&amp;nbsp; It does mean, however, that I think that they should have VERY limited use out there in the general application development universe, as I believe they have the capacity to do a great deal of harm.&lt;/p&gt;
&lt;p&gt;Why do I believe this?&amp;nbsp; Because fundamentally, partial methods seem to take away from the expressiveness of code and add greater potential for side effects.&amp;nbsp; The more time I spend thinking about partial methods, the less concerned I am with the first point.&amp;nbsp; For example, considering our set accessor, when using partial methods we would never actually know whether our method call would be called called - as the compiler would determine this based on the definition of the other class parts.&amp;nbsp; Initially, I thought that this was a really bad thing - until I thought more about how the template pattern was implemented by using virtual methods - and then thought about how it could be implemented with an interpreted language like JavaScript.&amp;nbsp; In both cases, the expectation for the developer is essentially the same - "If I have a custom implementation of the method, run it; otherwise, if there is a default implementation, run that; otherwise, do nothing."&amp;nbsp; With virtual methods, however, there was no semantic to express "do nothing" - you had to create an empty method body.&amp;nbsp; Therefore, partial methods actually allow for a more expressive grammar.&lt;/p&gt;
&lt;p&gt;That does not outweigh the badness of the second danger, however.&amp;nbsp; With virtual methods, you at least have some determinism around the call order.&amp;nbsp; For example, if I overrode a method in a class, I could sleep soundly at night knowing that my overridden method would be called every time it was called on my class.&amp;nbsp; If I did not override a method, I could have that same level of confidence knowing that my base class method would be called.&amp;nbsp; With partial classes, there is no 1:1 parent:child relationship - there is no limitation on the number of class parts that can be created - and the same is true of partial methods.&amp;nbsp; There is then (IMHO) a huge risk of unintentionally introducing side effects that are really difficult to debug.&lt;/p&gt;
&lt;p&gt;In conclusion, one of the questions I would raise is this.&amp;nbsp; If partial methods were essentially a language supplied performance optimization for people writing code generators, why make it a language feature at all?&amp;nbsp; Why not make it something implicit in the compiler - similar to how the C compiler automatically inlines simple methods?&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2934166" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Microsoft+.NET+Programming/default.aspx">Microsoft .NET Programming</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Architecture/default.aspx">Architecture</category></item><item><title>Linq for NHibernate</title><link>http://blogs.msdn.com/howard_dierking/archive/2007/04/09/linq-for-nhibernate.aspx</link><pubDate>Tue, 10 Apr 2007 03:42:28 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2066020</guid><dc:creator>hdierking</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/howard_dierking/comments/2066020.aspx</comments><wfw:commentRss>http://blogs.msdn.com/howard_dierking/commentrss.aspx?PostID=2066020</wfw:commentRss><description>&lt;p&gt;A while back, I posted on &lt;a href="http://blogs.msdn.com/howard_dierking/archive/2007/01/18/lambda-lambda-lambda.aspx"&gt;lambda expressions in C# 3.0&lt;/a&gt;.  In that post, I concluded by saying the following.
&lt;/p&gt;&lt;p&gt;"Personally, I would love to see somebody write an extension to NHibernate to allow use of Linq queries in the place of HQL – so if anyone's looking down that path, please let me know!"
&lt;/p&gt;&lt;p&gt;Well, it looks as though the ball was already rolling – looks like one of the &lt;a href="http://www.hibernate.org/343.html"&gt;NHibernate&lt;/a&gt; community greats, &lt;a href="http://ayende.com/Blog/Default.aspx"&gt;Oren Eini&lt;/a&gt;, is currently working on an implementation – and the best part – it looks like he's &lt;a href="http://ayende.com/Blog/archive/2007/03/17/Implementing-Linq-for-NHibernate-A-How-To-Guide--Part.aspx"&gt;reporting some of his discoveries&lt;/a&gt; along the way.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2066020" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Microsoft+.NET+Programming/default.aspx">Microsoft .NET Programming</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category></item><item><title>Orcas Certifications Follow-Up – Implications for MCPD</title><link>http://blogs.msdn.com/howard_dierking/archive/2007/03/25/orcas-certifications-follow-up-implications-for-mcpd.aspx</link><pubDate>Mon, 26 Mar 2007 08:43:58 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1950301</guid><dc:creator>hdierking</dc:creator><slash:comments>36</slash:comments><comments>http://blogs.msdn.com/howard_dierking/comments/1950301.aspx</comments><wfw:commentRss>http://blogs.msdn.com/howard_dierking/commentrss.aspx?PostID=1950301</wfw:commentRss><description>&lt;p&gt;I wanted to take a quick second to do 2 things.
&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Update you on our plans for a set of Orcas Technology Specialist exams and certifications
&lt;/li&gt;&lt;li&gt;Explain the role that these new TS certifications will play in the MCPD certifications
&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;So firstly, here's the updated plan for the Orcas/.NET 3.5 timeframe.  The names here may be different than the final names, but you should be able to get the general idea.  Also, I've highlighted the new exams.
&lt;/p&gt;&lt;div&gt;&lt;table style="border-collapse:collapse" border="0"&gt;&lt;colgroup&gt;&lt;col style="width:167px"/&gt;&lt;col style="width:204px"/&gt;&lt;/colgroup&gt;&lt;tbody valign="top"&gt;&lt;tr style="background: #4f81bd"&gt;&lt;td style="padding-left: 7px; padding-right: 7px; border-top:  solid #7ba0cd 1.0pt; border-left:  solid #7ba0cd 1.0pt; border-bottom:  solid #7ba0cd 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="color:white"&gt;&lt;strong&gt;Certification&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="padding-left: 7px; padding-right: 7px; border-top:  solid #7ba0cd 1.0pt; border-left:  none; border-bottom:  solid #7ba0cd 1.0pt; border-right:  solid #7ba0cd 1.0pt"&gt;&lt;p&gt;&lt;span style="color:white"&gt;&lt;strong&gt;Exams&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="background: #d3dfee"&gt;&lt;td style="padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  solid #7ba0cd 1.0pt; border-bottom:  solid #7ba0cd 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;strong&gt;MCTS: WPF&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #7ba0cd 1.0pt; border-right:  solid #7ba0cd 1.0pt"&gt;&lt;p&gt;&lt;span style="background-color:yellow"&gt;TS: WPF&lt;/span&gt; + 70-536&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  solid #7ba0cd 1.0pt; border-bottom:  solid #7ba0cd 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;strong&gt;MCTS: WCF&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #7ba0cd 1.0pt; border-right:  solid #7ba0cd 1.0pt"&gt;&lt;p&gt;&lt;span style="background-color:yellow"&gt;TS: WCF&lt;/span&gt; + 70-536&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="background: #d3dfee"&gt;&lt;td style="padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  solid #7ba0cd 1.0pt; border-bottom:  solid #7ba0cd 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;strong&gt;MCTS: WF&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #7ba0cd 1.0pt; border-right:  solid #7ba0cd 1.0pt"&gt;&lt;p&gt;&lt;span style="background-color:yellow"&gt;TS: WF&lt;/span&gt; + 70-536&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  solid #7ba0cd 1.0pt; border-bottom:  solid #7ba0cd 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;strong&gt;MCTS: ASP.NET 3.5&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #7ba0cd 1.0pt; border-right:  solid #7ba0cd 1.0pt"&gt;&lt;p&gt;&lt;span style="background-color:yellow"&gt;TS: ASP.NET 3.5&lt;/span&gt; + 70-536&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="background: #d3dfee"&gt;&lt;td style="padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  solid #7ba0cd 1.0pt; border-bottom:  solid #7ba0cd 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;strong&gt;MCTS: ADO.NET 3.5&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="padding-left: 7px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #7ba0cd 1.0pt; border-right:  solid #7ba0cd 1.0pt"&gt;&lt;p&gt;&lt;span style="background-color:yellow"&gt;TS: ADO.NET 3.5&lt;/span&gt; + 70-536&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;
 &lt;/p&gt;&lt;p&gt;Next, I've received several questions asking what will be the impact of this new content on the MCPD certification.  In order to best explain this, let's recap how the MCPD certification works.  First, your MCPD is valid for 3 years, starting when you receive the certification.  That means that even if we change the MCPD requirements a week after you obtain your certification, you do not have to fulfill the new requirements for 3 years (not to say, of course, that you shouldn't anyways).
&lt;/p&gt;&lt;p&gt;Now, let's look at what are the requirements for the MCPD credential.  It is a combination of 2 things: TS certifications + exams.  One thing I want to make clear up front – Personally, I really don't like upgrade exams.  Fortunately, the new gen program is really designed in such a way to support my ambitions of not having upgrade exams.  Sometime this coming year (not trying to be ambiguous here – I just don't know when yet), we will release the MCPD renewal requirements.  As an example, let's look at the MCPD: Web Developer.  In an Orcas world, this certification might look as follows.
&lt;/p&gt;&lt;p&gt;MCPD: Web Developer = TS: ASP.NET 3.5 + TS: ADO.NET 3.5 + EXAM: 70-547 (or new exam if we determine that Orcas technologies create new design decision trees)
&lt;/p&gt;&lt;p&gt;After the change, new entrants simply need to obtain all of the requirements.  For those of you who already hold an MCPD credential and need to renew it, you simply need to fulfill the requirements that you do not have.  For example, in the example above, if we do not revise 70-547, you simply need to obtain TS certifications in ASP.NET 3.5 and ADO.NET 3.5.
&lt;/p&gt;&lt;p&gt;This strategy ensures that we are able to keep up with the segments of the technology landscape that are changing without forcing you to reassess your knowledge on those areas that have not changed.  Additionally, in many cases (ASP.NET) it will be fairly obvious to you which new technologies will become requirements in future MCPD changes.  Because the TS certifications follow a release schedule that more closely aligns with those technologies, you can achieve many of the aforementioned MCPD requirements before we even make the program changes.
&lt;/p&gt;&lt;p&gt;Hopefully, this strategy is one that makes sense to you and is one that you can agree with.  As always, please let me know if you have any questions or concerns.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1950301" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Certifications/default.aspx">Certifications</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Microsoft+.NET+Programming/default.aspx">Microsoft .NET Programming</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category></item><item><title>An Orcas Question…</title><link>http://blogs.msdn.com/howard_dierking/archive/2007/03/02/an-orcas-question.aspx</link><pubDate>Sat, 03 Mar 2007 00:28:21 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1790295</guid><dc:creator>hdierking</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/howard_dierking/comments/1790295.aspx</comments><wfw:commentRss>http://blogs.msdn.com/howard_dierking/commentrss.aspx?PostID=1790295</wfw:commentRss><description>&lt;p&gt;So far, I've told you that we're planning new Technology Specialist certifications around the 3 main technologies in the .NET 3.0 stack.  Actually, because both the complete technology solutions and the exams will be released in the Orcas timeframe, these new certifications will roll up under the .NET 3.5 banner (I know – the whole new versioning strategy – yea – I get it…).  Anyways, because we are going to be releasing in the Orcas timeframe, there are several additional technologies that will be available.  Some of these technologies include language enhancements such as extension methods, lambda expressions, anonymous types, object initializers, etc…  Therefore, my question to you is as follows.  What are your thoughts around doing a .NET 3.5 foundation exam as a prerequisite exam to all of the other .NET 3.5 TS exams – much like how 70-536 was a prerequisite to the .NET 2.0 TS exams?  There are a few options as I see them.
&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Create a TS-level exam which would cover the items mentioned above in addition to basic .NET FCL content (basically, the 536 content that actually *was* foundational – not GDI+ stuff, etc…).  Make this exam a requirement for all .NET 3.5 TS certifications.  The positive aspects to this approach, as I see them, are that a) we can focus the foundational content a bit better than we did in 70-536 and b) we can cover the new general features of the .NET Framework 3.5.  The main problem with this approach is that it would require existing certification holders (folks who have already taken 70-536) to take another foundation exam.  Now, let me say that I don't think that re-validating existing skills is necessarily a bad thing.  However, I think it's problematic from a financial perspective – I would hate for existing certification holders to come away with the idea that such an exam was just another way to extract money from them.
&lt;/li&gt;&lt;li&gt;Do not create a new foundation exam around .NET 3.5 and make 70-536 as a prerequisite to all of the .NET 3.5 TS certifications.  Since a majority of the new language features in .NET 3.5 were added in support of Linq, move this content into an ADO.NET certification path.  The positive aspects of this approach are that a) we can leverage an existing exam and b) existing certification holders need only take the 3.5 specific exams (as they will already have passed 70-536).  The problem with this approach is that there is potentially some confusion around version numbers (requiring .NET 2.0 foundation as a part of the .NET 3.5 certification).
&lt;/li&gt;&lt;li&gt;Do not create a new foundation exam around .NET 3.5 and do not require a prerequisite exam for the .NET 3.5 TS certifications.  Since a majority of the new language features in .NET 3.5 were added in support of Linq, move this content into an ADO.NET certification path.  The positive aspects of this approach are a) there is no bleed over of version number (see above) and b) there is only 1 exam required in order to achieve certification in .NET 3.5.  The main problem (and this is big in my mind) is that new entrants are relatively unproven in terms of general .NET Framework skills.
&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Please keep in mind that the above in no way represents any formal plan.  These are only my thoughts on the matter and I want to get them out there as soon as I can so that you can give me yours.  It's always a relatively delicate balancing act to accommodate the needs of new entrants with the needs of existing certificate holders – and to complicate the matter slightly, I would really like to do that here without creating upgrade exams.
&lt;/p&gt;&lt;p&gt;I look forward to your feedback.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1790295" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Certifications/default.aspx">Certifications</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category></item><item><title>More C# 3.0 – Extension Methods</title><link>http://blogs.msdn.com/howard_dierking/archive/2007/02/09/more-c-3-0-extension-methods.aspx</link><pubDate>Sat, 10 Feb 2007 01:05:22 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1637503</guid><dc:creator>hdierking</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/howard_dierking/comments/1637503.aspx</comments><wfw:commentRss>http://blogs.msdn.com/howard_dierking/commentrss.aspx?PostID=1637503</wfw:commentRss><description>&lt;p&gt;A while back I wrote a &lt;a href="http://blogs.msdn.com/howard_dierking/archive/2007/01/18/lambda-lambda-lambda.aspx"&gt;post about lambda expressions in C# 3.0&lt;/a&gt; and how they are one of the enabling technologies behind &lt;a href="http://msdn2.microsoft.com/en-us/netframework/aa904594.aspx"&gt;Linq&lt;/a&gt;. I would like to continue that discussion today with a quick overview of something called extension methods. First, I want to say up front that I believe extension methods are one of those features that will be useful for framework developers – but bring a very high risk of abuse if used widely in a general sense. So with that out of the way, I'll cover what extension methods are, how they can be used, and what are some of the "gotchas". &lt;/p&gt; &lt;p&gt;First, an extension method is simply a new technique for extending a class without inheriting from the class, making a partial class, etc… The really interesting thing about this technique is in the implementation details. In C# 3.0, extension methods are implemented by creating a static class (which implies that the methods will be static methods) and using the 'this' modifier on the first method parameter. For example, consider the following. &lt;/p&gt; &lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; LinqTestsHarness.Extensions { &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;&lt;strong&gt;static&lt;/strong&gt;&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; TestExtensions { &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;&lt;strong&gt;static&lt;/strong&gt;&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SayHelloFromInt(&lt;span class="kwrd"&gt;&lt;strong&gt;this&lt;/strong&gt;&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; arg) { &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;      Console.WriteLine(&lt;span class="str"&gt;"Hello "&lt;/span&gt; + arg.ToString()); &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    } &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;  } &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;As we have described, the extension method is identified by the fact that it is a static method (in a static class) and that it has the 'this' modifier on its first parameter. OK – so now we've go this extension method – what do we do with it? If you remember our working definition of an extension method from above, the method allows us to extend an existing type – and that's exactly what our new method does. For example, we can now run the following code. &lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; LinqTestsHarness.Extensions; 

... 

&lt;span class="kwrd"&gt;int&lt;/span&gt; n = 5; 

n.SayHelloFromInt(); &lt;/pre&gt;
&lt;p&gt;And how did this work again? 2 things. First, we imported the namespace containing our extension method. Every time you import a namespace, you bring in every extension method that is defined within that namespace. The second important thing that allowed the above code to work is that we declared our variable (n) of type int – which is of course the type expected by our extension method. The following would not compile because of the type mismatch. &lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; LinqTestsHarness.Extensions; 

... 

&lt;span class="kwrd"&gt;string&lt;/span&gt; s = &lt;span class="str"&gt;"howard"&lt;/span&gt;; 

n.SayHelloFromInt();&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;So by now you should have a pretty decent understanding of how extension methods work – so let's take a look at how they are used by Linq. Consider the following Linq expression. &lt;/p&gt;&lt;pre class="csharpcode"&gt;IEnumerable&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; expr = from s &lt;span class="kwrd"&gt;in&lt;/span&gt; names 
  &lt;span class="kwrd"&gt;where&lt;/span&gt; s.Length == 5 
  orderby s 
  select s.ToUpper();&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;The Linq keyword such as 'where', 'orderby', etc… are simply shortcuts to extension methods defined in the System.Linq namespace. Therefore, the following is equivalent to the previous Linq expression.&lt;/p&gt;&lt;pre class="csharpcode"&gt;IEnumerable&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; expr = names 
  .Where(s =&amp;gt; s.Length == 5) 
  .OrderBy(s =&amp;gt; s) 
  .Select(s =&amp;gt; s.ToUpper());&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;So hopefully, you are now starting to see that Linq is not some sort of compiler magic. It is built on the very same language features that you have access to as you design and construct your solutions. Now, as we look at one potential application of extension methods, let me be quite clear that this is not a design pattern that I support – I am mentioning it here because I know that this is a pattern that many people do support, and if it is going to continue being used, extension methods are not a bad way to go about separating concerns. Let's consider object persistence. While there is significant debate over the "proper" architectural pattern for layer interactions, there is a school of thought that advocates the inclusion of persistence operations (Create, Read, Update, Delete) on business objects. One of the counter arguments to this approach is that you are then required to mix persistence code with business code and subsequently tie the business layer to a specific data access provider. In this context (let's forget about all of the other arguments both for and against this technique right now), extension methods provide a creative solution to the problem. For example, consider the following business entity class.&lt;/p&gt;
&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Person { &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;  &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; _name; &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;  &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; _age; &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;  &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; _canCode; &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; Person() { } &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; Person(&lt;span class="kwrd"&gt;string&lt;/span&gt; name) { &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;    Name = name; &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;  } &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; Person(&lt;span class="kwrd"&gt;string&lt;/span&gt; name, &lt;span class="kwrd"&gt;int&lt;/span&gt; age) : &lt;span class="kwrd"&gt;this&lt;/span&gt;(name) { &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    Age = age; &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;  } &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Name { &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;    get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _name; } &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;    set { _name = &lt;span class="kwrd"&gt;value&lt;/span&gt;; } &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;  } &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Age { &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;    get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _age; } &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;    set { _age = &lt;span class="kwrd"&gt;value&lt;/span&gt;; } &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;  } &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; CanCode { &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;    get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _canCode; } &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;    set { _canCode = &lt;span class="kwrd"&gt;value&lt;/span&gt;; } &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;  } &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ToString() { &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; Name; &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;  } &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;If you wanted to maintain your data access code in a separate assembly, yet still have the appearance of data access methods on this class, you could create your data access class as a static class and use extension methods for the data access functionality. This extension class would look like the following. &lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; LinqTestsHarness.DataAccess { 
  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; DataAccessExtensions { 
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Save(&lt;span class="kwrd"&gt;this&lt;/span&gt; Person arg) { 
      &lt;span class="rem"&gt;// ... &lt;/span&gt;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Delete(&lt;span class="kwrd"&gt;this&lt;/span&gt; Person arg) { 
      &lt;span class="rem"&gt;// ... &lt;/span&gt;
    } 
  } 
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;Just like in the previous case, using the extension method is a simple matter of importing the LinqTestsHarness.DataAccess namespace. The first parameter on the extension method constrains the method to only instances of the 'Person' class. Of course, all of the usual OO capabilities apply to extension methods. Were I using an ORM tool for my persistence, I could also create a marker interface and constrain the extension method to that interface rather than the concrete type. You can also create generic extension methods. However, my goal with this post is to simply give you an overview. &lt;/p&gt;
&lt;p&gt;Now – a word of caution. While extension methods can be a very handy tool for allowing frameworks to add functionality to existing object models, they should probably be approached with a degree of caution. Like any cross-cutting technique, extension methods can be a real pain when it comes to tracing and debugging. One thing that you absolutely must keep in mind with extension methods is that they are given the lowest priority in terms of method invocation. Practically, this means that if the object instance already contains a method (virtual or otherwise) with the same name as your extension method, that method will always be give precedence over your extension method. Therefore, there's always going to be some degree of brittleness if you design a solution that makes heavy use of extension methods because your extension methods and the object model on which the methods are applied will probably evolve quite independently. &lt;/p&gt;
&lt;p&gt;Secondly, and even more dangerous is the fact that although it appears as an instance methods, extension methods are of course static. What that means in IL terms is that extension methods use the 'call' instruction rather than the 'callvirt' instruction. Why is this important? Because the 'callvirt' instruction, the instruction called whenever you call an instance method on an object (in C#), checks for null and throws a 'NullReferenceException' if the object is null – the 'call' instruction does not. Therefore, the following code is perfectly legal.&lt;/p&gt;&lt;pre class="csharpcode"&gt;Person howard = &lt;span class="kwrd"&gt;null&lt;/span&gt;; 
howard.Save();&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;Now, obviously, there are a lot of cool things that you can do with extension methods, and I'm not trying to say that you should never use them. Obviously, the Linq team has gained tremendous value from them. However, like with all things in development – just because you have a new hammer, don't turn everything into a nail!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1637503" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Microsoft+.NET+Programming/default.aspx">Microsoft .NET Programming</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category><category domain="http://blogs.msdn.com/howard_dierking/archive/tags/Architecture/default.aspx">Architecture</category></item></channel></rss>