<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:blogChannel="http://backend.userland.com/blogChannelModule" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>MyViewState.NET</title>
    <description>Adventures in .NET Development</description>
    <link>http://www.myviewstate.net/blog/</link>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>BlogEngine.NET 1.5.0.7</generator>
    <language>en-US</language>
    <blogChannel:blogRoll>http://www.myviewstate.net/blog/opml.axd</blogChannel:blogRoll>
    <dc:creator>Kevin Babcock</dc:creator>
    <dc:title>MyViewState.NET</dc:title>
    <geo:lat>0.000000</geo:lat>
    <geo:long>0.000000</geo:long>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/kevinbabcock" type="application/rss+xml" /><item>
      <title>Telerik Q2 2009 Release News</title>
      <description>&lt;p align="justify"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="Telerik gift" border="0" alt="Telerik gift" align="right" src="http://www.myviewstate.net/blog/image.axd?picture=telerik_gift.png" width="220" height="180" /&gt; The &lt;a href="http://www.telerik.com/"&gt;Telerik&lt;/a&gt; Q2 2009 “Release Week” came to a close today, and I’m sure the brilliant developers there are already hard at work on the Q3 2009 stuff. But I’m just getting started with the goodies they released this week and wanted to share the excitement. In case you missed it, Telerik updated our accounts with shiny new bits for 7 product lines (&lt;a href="http://www.sitefinity.com"&gt;Sitefinity&lt;/a&gt; is on its own release cycle). If you aren’t already a Telerik user, go test out the trials and let them (and me!) know what you think.&lt;/p&gt;  &lt;p align="justify"&gt;Q2 2009 was hands-down the most exciting release I’ve seen yet. Not only did they surprise folks with the release of the &lt;a href="http://www.telerik.com/products/web-testing-tools.aspx"&gt;FREE automated web UI testing framework&lt;/a&gt; for ASP.NET AJAX and Silverlight, but they added a ton of new features to existing tools. The RadControls for ASP.NET AJAX got 4 new controls, an expanded set of &lt;a href="http://www.telerik.com/products/aspnet-ajax/visual-studio-extensions.aspx"&gt;extensions for Visual Studio&lt;/a&gt;, and plenty of upgrades to the other controls. Let’s also not forget the new &lt;a href="http://stylebuilder.telerik.com/"&gt;Visual Style Builder&lt;/a&gt;, which lets you quickly and easily create custom skins for the ASP.NET AJAX controls. The RadControls for Silverlight suite now features &lt;a href="http://www.telerik.com/products/silverlight/chart.aspx#9-3d-chart-types-for-silverlight"&gt;3D charts&lt;/a&gt; – the first of its kind in the Silverlight space – and a new &lt;a href="http://www.telerik.com/products/silverlight/scheduler.aspx"&gt;scheduler control&lt;/a&gt;. Telerik Reporting has a &lt;a href="http://www.telerik.com/products/reporting/wizards-tools.aspx#crosstab/table-wizard"&gt;Crosstab Wizard&lt;/a&gt;. And there were plenty of upgrades to go around for those of you using their WinForms, WPF, and OpenAccess ORM product lines as well. You can read the full details &lt;a href="http://www.telerik.com/products/whats-new-aspnet-ajax.aspx"&gt;here&lt;/a&gt;, &lt;a href="http://telerikwatch.com/2009/07/q2-2009-released.html"&gt;here&lt;/a&gt;, or watch the video &lt;a href="http://tv.telerik.com/whats-new/video/whats-new-q2-2009"&gt;here&lt;/a&gt;. If you want to play around with the new release, they have an upgraded set of &lt;a href="http://demos.telerik.com/aspnet-ajax/controls/examples/default/defaultcs.aspx"&gt;demos available online&lt;/a&gt;. Notice the new navigation bar at the top that lets you move from product to product – a nice touch!&lt;/p&gt;  &lt;p align="justify"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Telerik Demos - Screenshot" border="0" alt="Telerik Demos - Screenshot" src="http://www.myviewstate.net/blog/image.axd?picture=telerik-demos.jpg" width="604" height="239" /&gt; &lt;/p&gt;  &lt;p align="justify"&gt;And as if releasing a huge set of product enhancements wasn’t enough, Telerik generated a lot of excitement with &lt;a href="http://blogs.telerik.com/blogs/09-07-03/telerik_q2_2009_release_week_webinars.aspx"&gt;daily webinars&lt;/a&gt; to showcase the new product features and contests in which they gave away thousands of dollars worth of prizes. I’ve never seen my Twitter feed &lt;a href="http://search.twitter.com/search?q=telerikq209"&gt;so full of Telerik updates&lt;/a&gt;! If you missed the webinars they’re already posted to &lt;a href="http://tv.telerik.com/home"&gt;Telerik TV&lt;/a&gt;. They’re quick like that.&lt;/p&gt;  &lt;p align="justify"&gt;And if THAT wasn’t enough, Telerik also snuck in some new Oslo projects as well. Head over to &lt;a href="http://www.telerik.com/community/labs.aspx"&gt;Telerik Labs&lt;/a&gt; to check out the &lt;a href="http://www.telerik.com/community/labs/telerik-oslo-comparison-and-migration-tool.aspx"&gt;Oslo Comparison and Migration Tool&lt;/a&gt; and a new &lt;a href="http://www.telerik.com/community/labs/telerik-linq-to-m.aspx"&gt;LINQ to M&lt;/a&gt; implementation.&lt;/p&gt;  &lt;p align="justify"&gt;Telerik is really moving at &lt;em&gt;warp speed&lt;/em&gt; and continues to impress with the high quality products they put out. They really delivered this round and I can’t wait to see what’s next. The buzz I hear from the Telerik camp is that Q3 2009 is going to be even better.&lt;/p&gt;  &lt;p align="justify"&gt;Gig ‘em!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kevinbabcock/~4/lZGWZiMjdPI" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/kevinbabcock/~3/lZGWZiMjdPI/post.aspx</link>
      <author>Kevin Babcock</author>
      <comments>http://www.myviewstate.net/blog/post/2009/07/11/Telerik-Q2-2009-Release-News.aspx#comment</comments>
      <guid isPermaLink="false">http://www.myviewstate.net/blog/post.aspx?id=5f5eccee-44de-4b69-8686-fbf288374e14</guid>
      <pubDate>Sat, 11 Jul 2009 01:19:07 -0400</pubDate>
      <category>Tools</category>
      <dc:publisher>Kevin Babcock</dc:publisher>
      <pingback:server>http://www.myviewstate.net/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.myviewstate.net/blog/post.aspx?id=5f5eccee-44de-4b69-8686-fbf288374e14</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.myviewstate.net/blog/trackback.axd?id=5f5eccee-44de-4b69-8686-fbf288374e14</trackback:ping>
      <wfw:comment>http://www.myviewstate.net/blog/post/2009/07/11/Telerik-Q2-2009-Release-News.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.myviewstate.net/blog/syndication.axd?post=5f5eccee-44de-4b69-8686-fbf288374e14</wfw:commentRss>
    <feedburner:origLink>http://www.myviewstate.net/blog/post.aspx?id=5f5eccee-44de-4b69-8686-fbf288374e14</feedburner:origLink></item>
    <item>
      <title>Moderating Comments…</title>
      <description>&lt;p&gt;I am definitely &lt;em&gt;not&lt;/em&gt; a fan of comment moderation. But unfortunately I’ve had to turn comment moderation on for now to stop the recent deluge of spam. Once I have the time to add CAPTCHA functionality to the site I’ll turn off comment moderation (what a great opportunity to test out &lt;a href="http://demos.telerik.com/aspnet-ajax/captcha/examples/default/defaultcs.aspx"&gt;Telerik’s new control&lt;/a&gt;!). &lt;/p&gt;  &lt;p&gt;For those of you doing the manual spam thing: get a life and stop putting your links on my site. &lt;/p&gt;  &lt;p&gt;To the rest of you posting great discussions and feedback: thanks! I appreciate your input.&lt;/p&gt;  &lt;p&gt;Gig ‘em!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kevinbabcock/~4/lZgafg9cTQM" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/kevinbabcock/~3/lZgafg9cTQM/post.aspx</link>
      <author>Kevin Babcock</author>
      <comments>http://www.myviewstate.net/blog/post/2009/07/11/Moderating-Commentse280a6.aspx#comment</comments>
      <guid isPermaLink="false">http://www.myviewstate.net/blog/post.aspx?id=9de2562e-a680-445c-ad27-cb99cf9a6d14</guid>
      <pubDate>Sat, 11 Jul 2009 00:19:23 -0400</pubDate>
      <category>General</category>
      <dc:publisher>Kevin Babcock</dc:publisher>
      <pingback:server>http://www.myviewstate.net/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.myviewstate.net/blog/post.aspx?id=9de2562e-a680-445c-ad27-cb99cf9a6d14</pingback:target>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://www.myviewstate.net/blog/trackback.axd?id=9de2562e-a680-445c-ad27-cb99cf9a6d14</trackback:ping>
      <wfw:comment>http://www.myviewstate.net/blog/post/2009/07/11/Moderating-Commentse280a6.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.myviewstate.net/blog/syndication.axd?post=9de2562e-a680-445c-ad27-cb99cf9a6d14</wfw:commentRss>
    <feedburner:origLink>http://www.myviewstate.net/blog/post.aspx?id=9de2562e-a680-445c-ad27-cb99cf9a6d14</feedburner:origLink></item>
    <item>
      <title>Visual Studio Tip: Navigate Your Code</title>
      <description>&lt;p align="justify"&gt;When working in big projects one of my favorite ways to get around is to right-click on a variable, class name, or method call in code and select &lt;strong&gt;Go To Definition&lt;/strong&gt; from the context menu. &lt;/p&gt;  &lt;p align="justify"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="Visual Studio context menu" border="0" alt="Visual Studio context menu" src="http://www.myviewstate.net/blog/image.axd?picture=context_menu.jpg" width="150" height="214" /&gt; &lt;/p&gt;  &lt;p align="justify"&gt;This quickly opens the file where the object you clicked on is defined and navigates to its definition. Very handy when trying to sort through and figure out code you didn’t write. If you’re like me, you often find yourself wandering into the depths of someone else’s code and eventually you’re going to want to back out and get back to where you started. In Visual Studio there are two navigation buttons on the Standard toolbar menu which allow you to move forward and backwards through your navigation history.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="Visual Studio navigation buttons" border="0" alt="Visual Studio navigation buttons" src="http://www.myviewstate.net/blog/image.axd?picture=navigation_buttons.jpg" width="400" height="126" /&gt; &lt;/p&gt;  &lt;p align="justify"&gt;If you select the dropdown menu on the &lt;strong&gt;Backward&lt;/strong&gt; button you can also view and navigate to code you visited in your navigation history. It is organized by filename so you can easily locate the code you want.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="Visual Studio navigation history" border="0" alt="Visual Studio navigation history" src="http://www.myviewstate.net/blog/image.axd?picture=navigation_history.jpg" width="550" height="146" /&gt; &lt;/p&gt;  &lt;p align="justify"&gt;You can also use the keyboard shortcuts to navigate forward and backward more quickly:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div align="justify"&gt;Navigate Forward: &lt;strong&gt;&lt;font size="4"&gt;Ctrl + Shift + -&lt;/font&gt;&lt;/strong&gt;&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Navigate Backward: &lt;strong&gt;&lt;font size="4"&gt;Ctrl + -&lt;/font&gt;&lt;/strong&gt;&lt;/div&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p align="justify"&gt;The shortcuts aren’t as intuitive as I like, so I changed them. You change the keyboard shortcuts bound to the navigation commands as well in &lt;strong&gt;Tools | Options | Environment | Keyboard&lt;/strong&gt;. &lt;/p&gt;  &lt;p align="justify"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="Visual Studio keyboard binding options" border="0" alt="Visual Studio keyboard binding options" src="http://www.myviewstate.net/blog/image.axd?picture=keyboard_bindings.jpg" width="500" height="290" /&gt; &lt;/p&gt;  &lt;p align="justify"&gt;Enjoy!&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.myviewstate.net%2fblog%2fpost%2f2009%2f07%2f10%2fVisual-Studio-Tip-Navigate-Your-Code.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.myviewstate.net%2fblog%2fpost%2f2009%2f07%2f10%2fVisual-Studio-Tip-Navigate-Your-Code.aspx" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kevinbabcock/~4/CgUERhamP-4" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/kevinbabcock/~3/CgUERhamP-4/post.aspx</link>
      <author>Kevin Babcock</author>
      <comments>http://www.myviewstate.net/blog/post/2009/07/10/Visual-Studio-Tip-Navigate-Your-Code.aspx#comment</comments>
      <guid isPermaLink="false">http://www.myviewstate.net/blog/post.aspx?id=13b56d83-fca4-4f66-84ac-f30bb490d6a1</guid>
      <pubDate>Fri, 10 Jul 2009 23:38:58 -0400</pubDate>
      <category>Tools</category>
      <dc:publisher>Kevin Babcock</dc:publisher>
      <pingback:server>http://www.myviewstate.net/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.myviewstate.net/blog/post.aspx?id=13b56d83-fca4-4f66-84ac-f30bb490d6a1</pingback:target>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://www.myviewstate.net/blog/trackback.axd?id=13b56d83-fca4-4f66-84ac-f30bb490d6a1</trackback:ping>
      <wfw:comment>http://www.myviewstate.net/blog/post/2009/07/10/Visual-Studio-Tip-Navigate-Your-Code.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.myviewstate.net/blog/syndication.axd?post=13b56d83-fca4-4f66-84ac-f30bb490d6a1</wfw:commentRss>
    <feedburner:origLink>http://www.myviewstate.net/blog/post.aspx?id=13b56d83-fca4-4f66-84ac-f30bb490d6a1</feedburner:origLink></item>
    <item>
      <title>SQL Server: 'Saving changes is not permitted.'</title>
      <description>&lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Saving changes is not permitted. The changes you have made require the following tables to be dropped and re-created. You have either made changes to a table that can't be re-created or enabled the option Prevent saving changes that require the table to be re-created.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I ran into this fun little error message again tonight. It’s an annoying warning that pops up in SQL Server 2008 when performing certain changes to an existing schema. Apparently SQL Server 2008 drops and re-creates your tables when you make &lt;a href="http://msdn.microsoft.com/en-us/library/bb895146.aspx"&gt;certain changes&lt;/a&gt;, so it keeps you from accidentally screwing up your database by providing this error. There is a setting which you can change to get around this “feature” but I highly recommend you think it through before just turning the warning off. After all, you wouldn’t want to inadvertently drop an important table would you?&lt;/p&gt;  &lt;p&gt;To turn the warning off, go to &lt;strong&gt;Tools | Options | Designers | Table and Database Designers&lt;/strong&gt; in SQL Server Management Studio and de-select the &amp;quot;&lt;strong&gt;Prevent saving changes that require table re-creation&amp;quot; &lt;/strong&gt;checkbox. &lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; margin: 5px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="SQL Server Management Studio Options" border="0" alt="SQL Server Management Studio Options" src="http://www.myviewstate.net/blog/image.axd?picture=sql-error.jpg" width="550" height="319" /&gt; &lt;/p&gt;  &lt;p&gt;You can also turn the setting off from Visual Studio by de-selecting the same checkbox in &lt;strong&gt;Tools |Options | Database Tools | Table and Database Designers | Table and Database Options&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kevinbabcock/~4/mCABY5j5RaE" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/kevinbabcock/~3/mCABY5j5RaE/post.aspx</link>
      <author>Kevin Babcock</author>
      <comments>http://www.myviewstate.net/blog/post/2009/07/05/SQL-Server-Saving-changes-is-not-permitted.aspx#comment</comments>
      <guid isPermaLink="false">http://www.myviewstate.net/blog/post.aspx?id=f8697601-6c90-4a9c-a546-d19fca7c6a42</guid>
      <pubDate>Sun, 05 Jul 2009 23:38:49 -0400</pubDate>
      <category>Data Access and Storage</category>
      <dc:publisher>Kevin Babcock</dc:publisher>
      <pingback:server>http://www.myviewstate.net/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.myviewstate.net/blog/post.aspx?id=f8697601-6c90-4a9c-a546-d19fca7c6a42</pingback:target>
      <slash:comments>3</slash:comments>
      <trackback:ping>http://www.myviewstate.net/blog/trackback.axd?id=f8697601-6c90-4a9c-a546-d19fca7c6a42</trackback:ping>
      <wfw:comment>http://www.myviewstate.net/blog/post/2009/07/05/SQL-Server-Saving-changes-is-not-permitted.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.myviewstate.net/blog/syndication.axd?post=f8697601-6c90-4a9c-a546-d19fca7c6a42</wfw:commentRss>
    <feedburner:origLink>http://www.myviewstate.net/blog/post.aspx?id=f8697601-6c90-4a9c-a546-d19fca7c6a42</feedburner:origLink></item>
    <item>
      <title>Performing Set Operations with LINQ</title>
      <description>&lt;p&gt;LINQ’s set operations provide an easy (and fast!) way to filter or combine collections of objects in .NET. The four extension methods that perform set operations – Distinct, Except, Intersect, and Union – are available through the &lt;a href="http://msdn.microsoft.com/en-us/library/9eekhta0.aspx"&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/bb351562.aspx"&gt;IQueryable&amp;lt;T&amp;gt;&lt;/a&gt; interfaces and use an instance of &lt;a href="http://msdn.microsoft.com/en-us/library/ms132151.aspx"&gt;IEqualityComparer&amp;lt;T&amp;gt;&lt;/a&gt; to produce a result based on the presence or absence of equivalent elements. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;IEqualityComparer&amp;lt;T&amp;gt;&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;When performing set operations against collections of built-in types you don’t need to use your own IEqualityComparer&amp;lt;T&amp;gt; implementation; using the default, EqualityComparer&amp;lt;T&amp;gt;, is sufficient. However, if you are performing these operations against collections of your own complex types you will need to create your own and pass it in to the method call. The details of how IEqualityComparer&amp;lt;T&amp;gt; works is probably the single most important thing to understand when using set operations.&lt;/p&gt;  &lt;p&gt;The IEqualityComparer&amp;lt;T&amp;gt; interface requires implementation of two methods, &lt;font size="2" face="Courier New"&gt;Equals()&lt;/font&gt; and &lt;font size="2" face="Courier New"&gt;GetHashCode()&lt;/font&gt;. The first is an obvious requirement: you need to check the members of the set against each other for equality. The second has been a source of much confusion. If you take a look at the implementation of set operations in &lt;a href="http://www.red-gate.com/products/reflector/"&gt;.NET Reflector&lt;/a&gt;, you’ll see that when iterating through collections to perform equality checks, it uses &lt;strong&gt;both&lt;/strong&gt; &lt;font size="2" face="Courier New"&gt;Equals()&lt;/font&gt; and &lt;font size="2" face="Courier New"&gt;GetHashCode()&lt;/font&gt; to check for equality.&amp;#160; &lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;int hashCode = this.InternalGetHashCode(value);
for (int i = this.buckets[hashCode % this.buckets.Length] - 1; 
     i &amp;gt;= 0; 
     i = this.slots[i].next)
{
    if ((this.slots[i].hashCode == hashCode) 
        &amp;amp;&amp;amp; this.comparer.Equals(this.slots[i].value, value))
    {
        return true;
    }
}&lt;/pre&gt;

&lt;p&gt;Here we see that the hash code is retrieved from a method called &lt;font size="2" face="Courier New"&gt;InternalGetHashCode()&lt;/font&gt;, which in turn calls the IEqualityComparer&amp;lt;T&amp;gt;’s &lt;font size="2" face="Courier New"&gt;GetHashCode() &lt;/font&gt;method. The actual values are stored in a private member array called slots and then another private array, buckets, is used to map values to an index based on the hash code. This is a &lt;a href="http://en.wikipedia.org/wiki/Hash_table"&gt;hash table&lt;/a&gt; implementation, making value lookups very fast. It makes sense that we’d need two values considered to be equal to also return an identical hash code. Otherwise, the hash table would not work correctly and we’d have to iterate through the entire list of values to check each one for equality, which would seriously degrade performance. The use of hash tables is what makes the set operations so fast.&lt;/p&gt;

&lt;p&gt;So with this newfound understanding of how IEqualityComparer&amp;lt;T&amp;gt; is used with set operations, we can design custom implementations correctly. Let’s create two simple implementations to cover the general cases that I have run into: one in which the equality of an object is based on the value of a single member, and another in which equality is based on two or more members.&lt;/p&gt;

&lt;p&gt;For the first case, implementing IEqualityComparer&amp;lt;T&amp;gt; is simple:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class SimpleData
{
    public string Value { get; set; }
}

public class SimpleDataComparer : IEqualityComparer&amp;lt;SimpleData&amp;gt;
{
    public bool Equals(SimpleData x, SimpleData y)
    {
        return x.Value == y.Value;
    }

    public int GetHashCode(SimpleData obj)
    {
        return obj.Value.GetHashCode();
    }
}&lt;/pre&gt;

&lt;p&gt;I have a class, &lt;font size="2" face="Courier New"&gt;SimpleData&lt;/font&gt;, that has a single member I want to use to test my class for equality. Notice in the implementation of &lt;font size="2" face="Courier New"&gt;SimpleDataComparer&lt;/font&gt; that I don’t call the object’s &lt;font size="2" face="Courier New"&gt;GetHashCode()&lt;/font&gt; method, but instead call &lt;font size="2" face="Courier New"&gt;GetHashCode()&lt;/font&gt; on the member being used to compare the data. &lt;strong&gt;This is an important distinction&lt;/strong&gt;. Consider the following code snippet in which I use two &lt;font size="2" face="Courier New"&gt;SimpleData&lt;/font&gt; objects, each of which contains identical values. Calling &lt;font size="2" face="Courier New"&gt;GetHashCode()&lt;/font&gt; on these identical objects returns different values, whereas calling &lt;font size="2" face="Courier New"&gt;Value.GetHashCode()&lt;/font&gt; returns identical values.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;var data1 = new SimpleData { Value = &amp;quot;SomeValue&amp;quot; };
var data2 = new SimpleData { Value = &amp;quot;SomeValue2&amp;quot; };
var hashCode1 = data1.GetHashCode();        // returns 37121646
var hashCode2 = data2.GetHashCode();        // returns 45592480
var hashCode3 = data1.Value.GetHashCode();  // returns -840951029 
var hashCode4 = data2.Value.GetHashCode();  // returns -840951029&lt;/pre&gt;

&lt;p&gt;As you can see, calling the object’s &lt;font size="2" face="Courier New"&gt;GetHashCode() &lt;/font&gt;method returns different values, whereas calling it on the specific member we are comparing returns the same value. Of course, we could call &lt;font size="2" face="Courier New"&gt;SimpleData.GetHashCode()&lt;/font&gt; if we provided an overloaded implementation that returned identical values for equal objects. As an aside, don’t get too hung up on the negative hash code value that was returned. Internally the leftmost bit in the value is actually flipped, making it a positive value, before it is used.&lt;/p&gt;

&lt;p&gt;The second case I want to bring up is one in which you might want to use more than one member to determine equality. Consider the following example, in which I use a custom class, ComplexData. &lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;var data1 = new ComplexData 
    { FirstValue = 0.12, SecondValue = 1.45m, ThirdValue = &amp;quot;MyValue&amp;quot; };
var data2 = new ComplexData 
    { FirstValue = 0.12, SecondValue = 1.45m, ThirdValue = &amp;quot;MyValue&amp;quot; };
var hashCode1 = data1.GetHashCode();                // returns 22008501
var hashCode2 = data2.GetHashCode();                // returns 9008175
var hashCode3 = data1.FirstValue.GetHashCode()  ^   // returns -228796266 
                data1.SecondValue.GetHashCode() ^
                data1.ThirdValue.GetHashCode();     
var hashCode4 = data2.FirstValue.GetHashCode()  ^   // returns -228796266
                data2.SecondValue.GetHashCode() ^
                data2.ThirdValue.GetHashCode();&lt;/pre&gt;

&lt;p&gt;If I want to test for equality using multiple members of my custom class I must ensure that &lt;font size="2" face="Courier New"&gt;GetHashCode()&lt;/font&gt; returns a unique value based on these each unique set of values for my objects. As you’ve seen in the example above, this can be accomplished very easily by calling &lt;font size="2" face="Courier New"&gt;GetHashCode() &lt;/font&gt;on each value used in the comparison and then combining the results with an exclusive OR operator (^). Consider the following implementation:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class ComplexDataDataComparer : IEqualityComparer&amp;lt;ComplexData&amp;gt;
{
    public bool Equals(ComplexData x, ComplexData y)
    {
        return x.FirstValue  == y.FirstValue  &amp;amp;&amp;amp; 
               x.SecondValue == y.SecondValue &amp;amp;&amp;amp; 
               x.ThirdValue  == y.ThirdValue;
    }

    public int GetHashCode(ComplexData obj)
    {
        return obj.FirstValue.GetHashCode()  ^
               obj.SecondValue.GetHashCode() ^
               obj.ThirdValue.GetHashCode();
    }
}&lt;/pre&gt;

&lt;p&gt;So there you have it. It’s been a somewhat length explanation, but I’ve seen quite a few questions in forums and on blogs regarding how to properly implement IEqualityComparer&amp;lt;T&amp;gt; (and why). And since this is a crucial element when performing set operations on complex types, it must be understood. So let’s move on to set operations and how we can use what we’ve learned so far to take advantage of this great LINQ functionality. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;Distinct&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;font size="2" face="Courier New"&gt;Distinct()&lt;/font&gt; method returns all objects that are unique in the set. &lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;var numbers = new List&amp;lt;int&amp;gt; { 1, 2, 3, 2, 4, 1 };
// returns { 1, 2, 3, 4 }
var distinctNumbers = numbers.Distinct();          &lt;/pre&gt;

&lt;p&gt;You can also pass in an instance of your own class to compare for equality:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;var set = new List&amp;lt;ComplexData&amp;gt;
{
    new ComplexData { FirstValue = 1.2, SecondValue = 0.1m, ThirdValue = &amp;quot;Ab&amp;quot; },
    new ComplexData { FirstValue = 3.1, SecondValue = 9.7m, ThirdValue = &amp;quot;Cd&amp;quot; },
    new ComplexData { FirstValue = 1.2, SecondValue = 0.1m, ThirdValue = &amp;quot;Ab&amp;quot; },
    new ComplexData { FirstValue = 2.1, SecondValue = 3.4m, ThirdValue = &amp;quot;Xy&amp;quot; }
};
var comparer = new ComplexDataDataComparer();
var distinctSet = set.Distinct&amp;lt;ComplexData&amp;gt;(comparer);&lt;/pre&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; margin: 5px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="distinct set operation" border="0" alt="distinct set operation" src="http://www.myviewstate.net/blog/image.axd?picture=distinct.jpg" width="500" height="192" /&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;Except&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;font size="2" face="Courier New"&gt;Except()&lt;/font&gt; method returns the unique set of objects from one set that do not appear in a second set.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;var numbers = new List&amp;lt;int&amp;gt; { 1, 2, 3, 2, 4, 1 };
var otherNumbers = new List&amp;lt;int&amp;gt; { 3, 4, 1, 9, 4, 7 };
// returns { 2 }
var filteredNumbers = numbers.Except(otherNumbers);    &lt;/pre&gt;

&lt;p&gt;You can also pass in an instance of your own class to compare for equality:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;var set = new List&amp;lt;ComplexData&amp;gt;
{
    new ComplexData { FirstValue = 1.2, SecondValue = 0.1m, ThirdValue = &amp;quot;Ab&amp;quot; },
    new ComplexData { FirstValue = 3.1, SecondValue = 9.7m, ThirdValue = &amp;quot;Cd&amp;quot; },
    new ComplexData { FirstValue = 1.2, SecondValue = 0.1m, ThirdValue = &amp;quot;Ab&amp;quot; },
    new ComplexData { FirstValue = 2.1, SecondValue = 3.4m, ThirdValue = &amp;quot;Xy&amp;quot; }
};
var secondSet = new List&amp;lt;ComplexData&amp;gt;
{
    new ComplexData { FirstValue = 2.1, SecondValue = 3.4m, ThirdValue = &amp;quot;Xy&amp;quot; },
    new ComplexData { FirstValue = 7.1, SecondValue = 4.5m, ThirdValue = &amp;quot;Ef&amp;quot; },
    new ComplexData { FirstValue = 3.1, SecondValue = 9.7m, ThirdValue = &amp;quot;Cd&amp;quot; },
    new ComplexData { FirstValue = 0.4, SecondValue = 3.9m, ThirdValue = &amp;quot;Rs&amp;quot; }
};
var comparer = new ComplexDataDataComparer();
var filteredSet = set.Except(secondSet, comparer);&lt;/pre&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; margin: 5px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="except set operation" border="0" alt="except set operation" src="http://www.myviewstate.net/blog/image.axd?picture=except.jpg" width="500" height="315" /&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;Intersect&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;font size="2" face="Courier New"&gt;Intersect()&lt;/font&gt; method returns all objects that two sets share in common.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;var numbers = new List&amp;lt;int&amp;gt; { 1, 2, 3, 2, 4, 1 };
var otherNumbers = new List&amp;lt;int&amp;gt; { 3, 4, 1, 9, 4, 7 };
// returns { 1, 3, 4 }
var commonNumbers = numbers.Intersect(otherNumbers); &lt;/pre&gt;

&lt;p&gt;You can also pass in an instance of your own class to compare for equality:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;var set = new List&amp;lt;ComplexData&amp;gt;
{
    new ComplexData { FirstValue = 1.2, SecondValue = 0.1m, ThirdValue = &amp;quot;Ab&amp;quot; },
    new ComplexData { FirstValue = 3.1, SecondValue = 9.7m, ThirdValue = &amp;quot;Cd&amp;quot; },
    new ComplexData { FirstValue = 1.2, SecondValue = 0.1m, ThirdValue = &amp;quot;Ab&amp;quot; },
    new ComplexData { FirstValue = 2.1, SecondValue = 3.4m, ThirdValue = &amp;quot;Xy&amp;quot; }
};
var secondSet = new List&amp;lt;ComplexData&amp;gt;
{
    new ComplexData { FirstValue = 2.1, SecondValue = 3.4m, ThirdValue = &amp;quot;Xy&amp;quot; },
    new ComplexData { FirstValue = 7.1, SecondValue = 4.5m, ThirdValue = &amp;quot;Ef&amp;quot; },
    new ComplexData { FirstValue = 3.1, SecondValue = 9.7m, ThirdValue = &amp;quot;Cd&amp;quot; },
    new ComplexData { FirstValue = 0.4, SecondValue = 3.9m, ThirdValue = &amp;quot;Rs&amp;quot; }
};
var comparer = new ComplexDataDataComparer();
var commonSet = set.Intersect(secondSet, comparer);&lt;/pre&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; margin: 5px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="intersect set operation" border="0" alt="intersect set operation" src="http://www.myviewstate.net/blog/image.axd?picture=intersect.jpg" width="500" height="344" /&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;Union&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;font size="2" face="Courier New"&gt;Union()&lt;/font&gt; method returns the combined set of unique objects from two sets.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;var numbers = new List&amp;lt;int&amp;gt; { 1, 2, 3, 2, 4, 1 };
var otherNumbers = new List&amp;lt;int&amp;gt; { 3, 4, 1, 9, 4, 7 };
// returns { 1, 2, 3, 4, 9, 7 }
var combinedUniqueNumbers = numbers.Union(otherNumbers); &lt;/pre&gt;

&lt;p&gt;You can also pass in an instance of your own class to compare for equality:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;var set = new List&amp;lt;ComplexData&amp;gt;
{
    new ComplexData { FirstValue = 1.2, SecondValue = 0.1m, ThirdValue = &amp;quot;Ab&amp;quot; },
    new ComplexData { FirstValue = 3.1, SecondValue = 9.7m, ThirdValue = &amp;quot;Cd&amp;quot; },
    new ComplexData { FirstValue = 1.2, SecondValue = 0.1m, ThirdValue = &amp;quot;Ab&amp;quot; },
    new ComplexData { FirstValue = 2.1, SecondValue = 3.4m, ThirdValue = &amp;quot;Xy&amp;quot; }
};
var secondSet = new List&amp;lt;ComplexData&amp;gt;
{
    new ComplexData { FirstValue = 2.1, SecondValue = 3.4m, ThirdValue = &amp;quot;Xy&amp;quot; },
    new ComplexData { FirstValue = 7.1, SecondValue = 4.5m, ThirdValue = &amp;quot;Ef&amp;quot; },
    new ComplexData { FirstValue = 3.1, SecondValue = 9.7m, ThirdValue = &amp;quot;Cd&amp;quot; },
    new ComplexData { FirstValue = 0.4, SecondValue = 3.9m, ThirdValue = &amp;quot;Rs&amp;quot; }
};
var comparer = new ComplexDataDataComparer();
var combinedUniqueValues = set.Union(secondSet, comparer);&lt;/pre&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; margin: 5px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="union set operation" border="0" alt="union set operation" src="http://www.myviewstate.net/blog/image.axd?picture=union.jpg" width="500" height="467" /&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;Wrap Up&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Using set operations is very easy and can be used to perform fast set operations on your collections. When performing set operations on collections of complex types, it is important to understand how to properly implement IEqualityComparer&amp;lt;T&amp;gt;. I used LINQ to Objects in the examples of this blog post, but you can just as easily take this concepts to LINQ to SQL, LINQ to Entities, or other LINQ implementations. &lt;/p&gt;

&lt;p&gt;Have fun!&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.myviewstate.net%2fblog%2fpost%2f2009%2f07%2f01%2fPerforming-Set-Operations-with-LINQ.aspx"&gt;&lt;img border="0" alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.myviewstate.net%2fblog%2fpost%2f2009%2f07%2f01%2fPerforming-Set-Operations-with-LINQ.aspx" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kevinbabcock/~4/KesRH17H0Vk" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/kevinbabcock/~3/KesRH17H0Vk/post.aspx</link>
      <author>Kevin Babcock</author>
      <comments>http://www.myviewstate.net/blog/post/2009/07/01/Performing-Set-Operations-with-LINQ.aspx#comment</comments>
      <guid isPermaLink="false">http://www.myviewstate.net/blog/post.aspx?id=dbfdd30d-6d46-43e5-aaa2-f29fef4c18bb</guid>
      <pubDate>Wed, 01 Jul 2009 23:59:44 -0400</pubDate>
      <category>General Development</category>
      <dc:publisher>Kevin Babcock</dc:publisher>
      <pingback:server>http://www.myviewstate.net/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.myviewstate.net/blog/post.aspx?id=dbfdd30d-6d46-43e5-aaa2-f29fef4c18bb</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://www.myviewstate.net/blog/trackback.axd?id=dbfdd30d-6d46-43e5-aaa2-f29fef4c18bb</trackback:ping>
      <wfw:comment>http://www.myviewstate.net/blog/post/2009/07/01/Performing-Set-Operations-with-LINQ.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.myviewstate.net/blog/syndication.axd?post=dbfdd30d-6d46-43e5-aaa2-f29fef4c18bb</wfw:commentRss>
    <feedburner:origLink>http://www.myviewstate.net/blog/post.aspx?id=dbfdd30d-6d46-43e5-aaa2-f29fef4c18bb</feedburner:origLink></item>
    <item>
      <title>Hey jQuery lovers, ASP.NET AJAX can do Ajax too!</title>
      <description>&lt;p&gt;I’m a big fan of &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;. I’m no expert, but with a copy of &lt;a href="http://www.amazon.com/jQuery-Action-Bear-Bibeault/dp/1933988355"&gt;&lt;em&gt;jQuery in Action&lt;/em&gt;&lt;/a&gt; on my desk and &lt;strike&gt;Google&lt;/strike&gt; &lt;a href="http://www.bing.com/"&gt;Bing&lt;/a&gt; at my fingertips I can do a lot of cool things with it. One of the ways I often see people using jQuery is to make Ajax requests. jQuery provides a great library which should take care of just about all your Ajax needs, if you are an UpdatePanel-free web developer. I’ve &lt;a href="http://www.myviewstate.net/blog/post/2009/05/06/Disabling-Browser-Cache-when-Making-Ajax-Calls-with-jQuery.aspx"&gt;blogged about it&lt;/a&gt; to a small degree, but for more in-depth details you can read about it &lt;a href="http://docs.jquery.com/Ajax"&gt;here&lt;/a&gt;. For a quick example, here’s how you might make an Ajax call using jQuery:&lt;/p&gt;  &lt;pre class="brush: js;"&gt;$.ajax({
    url: &amp;quot;Services/Customers.svc&amp;quot;,
    type: &amp;quot;GET&amp;quot;,
    cache: false,
    success: getCustomersCompleteHandler
});&lt;/pre&gt;

&lt;p&gt;What amazes me is when I see folks using jQuery when &lt;em&gt;all&lt;/em&gt; they need is Ajax functionality. If you’re using ASP.NET, you shouldn’t be surprised to know that it’s already provided for you in the client-side library. When you add service references to your ScriptManager, the JavaScript proxies it generates aren’t magic code; they make explicit calls into the ASP.NET AJAX library to perform service calls. You can too!&lt;/p&gt;

&lt;p&gt;Using the &lt;a href="http://www.asp.net/AJAX/Documentation/Live/ClientReference/Sys.Net/WebRequestClass/default.aspx"&gt;WebRequest&lt;/a&gt; class, making Ajax calls is just as easy with ASP.NET AJAX:&lt;/p&gt;

&lt;pre class="brush: js;"&gt;function getCustomers(startIndex, rowCount) {
    var request = new Sys.Net.WebRequest();
    var url = String.format(&amp;quot;Services/Customers.svc/?i={0}&amp;amp;c={1}&amp;quot;, startIndex, rowCount);
    request.set_url(url);
    request.set_httpVerb(&amp;quot;GET&amp;quot;);
    request.add_completed(getCustomersCompleted);
    request.invoke();
}&lt;/pre&gt;

&lt;p&gt;Upon completion of the request you can access returned data or handle timeouts and aborted requests through the &lt;a href="http://www.asp.net/AJAX/Documentation/Live/ClientReference/Sys.Net/WebRequestExecutorClass/default.aspx"&gt;WebRequestExecutor&lt;/a&gt; object that is passed to the event handler.&lt;/p&gt;

&lt;pre class="brush: js;"&gt;function getCustomersCompleted(executor, args) {
    if (executor.get_responseAvailable()) {
        var data = executor.get_responseData();
        var jsonData = eval(&amp;quot;(&amp;quot; + data + &amp;quot;)&amp;quot;);
        loadContent(jsonData);
    }
    else if (executor.get_timedOut()) {
        // handle request timeout
    }
    else if (executor.get_aborted()) {
        // handle aborted request
    }
}&lt;/pre&gt;

&lt;p&gt;I built a very simple client-side “grid” that offers paging functionality and retrieves all its data from a web service. You can see that each request made from the ASP.NET AJAX library invokes the web service and returns only the minimum amount of data necessary to update the grid.&lt;/p&gt;

&lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 5px auto; display: block; float: none; border-top: 0px; border-right: 0px" title="Examining a web service request in Internet Explorer Web Development Helper" border="0" alt="Examining a web service request in Internet Explorer Web Development Helper" src="http://www.myviewstate.net/blog/image.axd?picture=service_request.jpg" width="500" height="408" /&gt; &lt;/p&gt;

&lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 5px auto; display: block; float: none; border-top: 0px; border-right: 0px" title="Examining a web service response in Internet Explorer Web Development Helper" border="0" alt="Examining a web service response in Internet Explorer Web Development Helper" src="http://www.myviewstate.net/blog/image.axd?picture=service_response.jpg" width="500" height="569" /&gt; &lt;/p&gt;

&lt;p&gt;Check out the [&lt;a href="http://www.myviewstate.net/demos/clientsideajax/default.aspx"&gt;LIVE DEMO&lt;/a&gt;], or download the [&lt;a href="http://www.myviewstate.net/demos/clientsideajaxexample.zip"&gt;SOURCE CODE&lt;/a&gt;], to see it in action.&lt;/p&gt;

&lt;p&gt;If you’re already using jQuery to add other rich functionality to your site then it makes sense to use it for your Ajax needs as well. But if all you need is Ajax, don’t forget that the ASP.NET AJAX library offers the same functionality without the need to manage yet another client-side library in your web app. It’s good to have options.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.myviewstate.net%2fblog%2fpost%2f2009%2f06%2f26%2fHey-jQuery-lovers-ASPNET-AJAX-can-do-Ajax-too!.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.myviewstate.net%2fblog%2fpost%2f2009%2f06%2f26%2fHey-jQuery-lovers-ASPNET-AJAX-can-do-Ajax-too!.aspx" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kevinbabcock/~4/twyRrlsxswo" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/kevinbabcock/~3/twyRrlsxswo/post.aspx</link>
      <author>Kevin Babcock</author>
      <comments>http://www.myviewstate.net/blog/post/2009/06/26/Hey-jQuery-lovers-ASPNET-AJAX-can-do-Ajax-too!.aspx#comment</comments>
      <guid isPermaLink="false">http://www.myviewstate.net/blog/post.aspx?id=3631851d-8878-46f1-8dfb-27fe805eb4da</guid>
      <pubDate>Fri, 26 Jun 2009 00:21:53 -0400</pubDate>
      <category>Web Development</category>
      <dc:publisher>Kevin Babcock</dc:publisher>
      <pingback:server>http://www.myviewstate.net/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.myviewstate.net/blog/post.aspx?id=3631851d-8878-46f1-8dfb-27fe805eb4da</pingback:target>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://www.myviewstate.net/blog/trackback.axd?id=3631851d-8878-46f1-8dfb-27fe805eb4da</trackback:ping>
      <wfw:comment>http://www.myviewstate.net/blog/post/2009/06/26/Hey-jQuery-lovers-ASPNET-AJAX-can-do-Ajax-too!.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.myviewstate.net/blog/syndication.axd?post=3631851d-8878-46f1-8dfb-27fe805eb4da</wfw:commentRss>
    <feedburner:origLink>http://www.myviewstate.net/blog/post.aspx?id=3631851d-8878-46f1-8dfb-27fe805eb4da</feedburner:origLink></item>
    <item>
      <title>JavaScript Shortcuts</title>
      <description>&lt;p&gt;JavaScript is definitely an interesting language. Unlike typical server-side code, we will often sacrifice readability for brevity in order to save a few bytes. Thanks to the many JavaScript compression apps out there, we don’t have to worry about this as much. But there are a few shortcuts I like to use from time to time which keep my client script terse, albeit a little less readable than using alternative means.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;|| as a null coalescing operator&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;A null coalescing operator returns the value to its right only if the value to its left is null. Here is an example of a null coalescing operator (??) in C#:&lt;/p&gt;  &lt;pre class="brush: csharp; gutter: false;"&gt;public string GetWebAddress(protocol, url) 
{
    protocol = protocol ?? &amp;quot;http://&amp;quot;;
    return protocol + url; 
}
string p = &amp;quot;https://&amp;quot;;
string url = &amp;quot;www.mysite.com&amp;quot;;
string address = getWebAddress(p, url);    // returns &amp;quot;https://www.mysite.com&amp;quot;
string address = getWebAddress(null, url); // returns &amp;quot;http://www.mysite.com&amp;quot;&lt;/pre&gt;

&lt;p&gt;There is no null coalescing operator in JavaScript. However, you can use the logical OR operator (||)&amp;#160; in its place. Here is similar code in JavaScript:&lt;/p&gt;

&lt;pre class="brush: js; gutter: false;"&gt;function getWebAddress(protocol, url) {
    protocol = protocol || &amp;quot;http://&amp;quot;;
    return protocol + url; 
}
var p = &amp;quot;https://&amp;quot;, url = &amp;quot;www.mysite.com&amp;quot;;
var address1 = getWebAddress(p, url);    // returns &amp;quot;http://www.mysite.com&amp;quot;
var address2 = getWebAddress(null, url); // returns &amp;quot;https://www.mysite.com&amp;quot;&lt;/pre&gt;

&lt;p&gt;This is logically equivalent to&lt;/p&gt;

&lt;pre class="brush: js; gutter: false;"&gt;function getWebAddress(protocol, url) {
    if (protocol === null) {
        protocol = &amp;quot;http://&amp;quot;;
    }
    return protocol + url; 
}
var p = &amp;quot;https://&amp;quot;, url = &amp;quot;www.mysite.com&amp;quot;;
var address1 = getWebAddress(p, url);    // returns &amp;quot;http://www.mysite.com&amp;quot;
var address2 = getWebAddress(null, url); // returns &amp;quot;https://www.mysite.com&amp;quot;&lt;/pre&gt;

&lt;p&gt;But the first method, using the logical OR operator, is much more compact.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;!! for quick boolean conversion&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can quickly cast JavaScript variables to boolean values using the double exclamation (!!). This operation will convert any non-null, non-zero value to true and all others to false.&lt;/p&gt;

&lt;pre class="brush: js; gutter: false;"&gt;var obj = { name: 'Kevin' };
var arr = [ '1', 0, '0' ];
var a = !!true;         // True
var b = !!false;        // False
var c = !!'true';       // True
var d = !!'false';      // True
var e = !!5;            // True
var f = !!0;            // False
var g = !!null;         // False
var h = !![];           // True
var i = !!{};           // True   
var j = !!'undefined';  // True
var k = !!obj.name;     // True
var l = !!obj.age;      // False
var m = !!arr[0];       // True
var n = !!arr[1];       // False
var o = !!arr[2];       // True
var p = !!arr[3];       // False&lt;/pre&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.myviewstate.net%2fblog%2fpost%2f2009%2f06%2f24%2fJavaScript-Shortcuts.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.myviewstate.net%2fblog%2fpost%2f2009%2f06%2f24%2fJavaScript-Shortcuts.aspx" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kevinbabcock/~4/l_UT9lqgOb8" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/kevinbabcock/~3/l_UT9lqgOb8/post.aspx</link>
      <author>Kevin Babcock</author>
      <comments>http://www.myviewstate.net/blog/post/2009/06/24/JavaScript-Shortcuts.aspx#comment</comments>
      <guid isPermaLink="false">http://www.myviewstate.net/blog/post.aspx?id=393afd49-e392-46d2-a4b8-175ce9cf7081</guid>
      <pubDate>Wed, 24 Jun 2009 21:26:26 -0400</pubDate>
      <category>Web Development</category>
      <dc:publisher>Kevin Babcock</dc:publisher>
      <pingback:server>http://www.myviewstate.net/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.myviewstate.net/blog/post.aspx?id=393afd49-e392-46d2-a4b8-175ce9cf7081</pingback:target>
      <slash:comments>3</slash:comments>
      <trackback:ping>http://www.myviewstate.net/blog/trackback.axd?id=393afd49-e392-46d2-a4b8-175ce9cf7081</trackback:ping>
      <wfw:comment>http://www.myviewstate.net/blog/post/2009/06/24/JavaScript-Shortcuts.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.myviewstate.net/blog/syndication.axd?post=393afd49-e392-46d2-a4b8-175ce9cf7081</wfw:commentRss>
    <feedburner:origLink>http://www.myviewstate.net/blog/post.aspx?id=393afd49-e392-46d2-a4b8-175ce9cf7081</feedburner:origLink></item>
    <item>
      <title>RadControls for ASP.NET AJAX Q2 2009 Beta Available</title>
      <description>&lt;p align="justify"&gt;I’m a little late to the party, but I wanted to toss a quick plug to the folks at Telerik for the &lt;a href="http://blogs.telerik.com/blogs/09-06-17/try_the_new_beta_now.aspx"&gt;Beta release&lt;/a&gt; of their Q2 2009 RadControls for ASP.NET AJAX suite. If you’re like me and can’t wait another few weeks for the official release, you can download and start playing with the beta version today. It’s got some great new features, some of which I hope to cover right here. &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;     &lt;div align="justify"&gt;Four, count them, FOUR new controls: RadBinaryImage, RadCaptcha, RadListBox, and RadXmlHttpPanel. Wow! Check out the &lt;a href="http://demos.telerik.com/aspnet-ajax-beta/Controls/Examples/Default/DefaultCS.aspx"&gt;demos&lt;/a&gt;. &lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;&lt;a href="http://www.telerik.com/products/aspnet-ajax/visual-studio-extensions.aspx"&gt;Visual Studio Extensions&lt;/a&gt;. Templates and wizards covering common application scenarios, among other things. &lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;Control improvements &amp;amp; bug fixes. There are quite a few new features for many of the controls, and bug fixes all around. It looks like the RadScheduler and RadGrid got a great deal of attention, but they aren’t the only ones! &lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;A sleek &lt;a href="http://blogs.telerik.com/blogs/09-05-28/the_new_installer_of_radcontrols_for_asp_net_ajax.aspx"&gt;new installer&lt;/a&gt;. The installation itself still takes about the same amount of time, but the new installer is a welcome change from the old full-screen installer. &lt;/div&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p align="justify"&gt;&lt;img style="border-right-width: 0px; margin: 5px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Telerik RadControls for ASP.NET AJAX installer" border="0" alt="Telerik RadControls for ASP.NET AJAX installer" src="http://www.myviewstate.net/blog/image.axd?picture=telerik_installer_1.jpg" width="500" height="379" /&gt; &lt;/p&gt;  &lt;p align="justify"&gt;&lt;img style="border-right-width: 0px; margin: 5px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Telerik RadControls for ASP.NET AJAX installer" border="0" alt="Telerik RadControls for ASP.NET AJAX installer" src="http://www.myviewstate.net/blog/image.axd?picture=telerik_installer_2.jpg" width="500" height="379" /&gt; &lt;/p&gt;  &lt;p align="justify"&gt;Go &lt;a href="http://www.telerik.com/products/aspnet-ajax/whats-new/release-history/q2-2009-beta-version-2009-2-616.aspx"&gt;read more&lt;/a&gt; about the new features, or download the controls and discover the new features for yourself.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kevinbabcock/~4/UszoXTqnVQ8" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/kevinbabcock/~3/UszoXTqnVQ8/post.aspx</link>
      <author>Kevin Babcock</author>
      <comments>http://www.myviewstate.net/blog/post/2009/06/23/RadControls-for-ASPNET-AJAX-Q2-2009-Beta-Available.aspx#comment</comments>
      <guid isPermaLink="false">http://www.myviewstate.net/blog/post.aspx?id=12b38f8e-7f95-4917-bddb-04ae875fd7ee</guid>
      <pubDate>Tue, 23 Jun 2009 21:28:53 -0400</pubDate>
      <category>Web Development</category>
      <dc:publisher>Kevin Babcock</dc:publisher>
      <pingback:server>http://www.myviewstate.net/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.myviewstate.net/blog/post.aspx?id=12b38f8e-7f95-4917-bddb-04ae875fd7ee</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.myviewstate.net/blog/trackback.axd?id=12b38f8e-7f95-4917-bddb-04ae875fd7ee</trackback:ping>
      <wfw:comment>http://www.myviewstate.net/blog/post/2009/06/23/RadControls-for-ASPNET-AJAX-Q2-2009-Beta-Available.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.myviewstate.net/blog/syndication.axd?post=12b38f8e-7f95-4917-bddb-04ae875fd7ee</wfw:commentRss>
    <feedburner:origLink>http://www.myviewstate.net/blog/post.aspx?id=12b38f8e-7f95-4917-bddb-04ae875fd7ee</feedburner:origLink></item>
    <item>
      <title>ASP.NET AJAX &amp; Type-safe parameters</title>
      <description>&lt;blockquote&gt;   &lt;p align="justify"&gt;The information in this post was written for the ASP.NET AJAX 4.0 Preview 4, and is subject to change with future releases.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="justify"&gt;&lt;img style="border-right-width: 0px; margin: 5px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="asp.net logo" border="0" alt="asp.net logo" src="http://www.myviewstate.net/blog/image.axd?picture=aspnet.png" width="400" height="112" /&gt; &lt;/p&gt;  &lt;p align="justify"&gt;A new feature in the &lt;a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24645"&gt;ASP.NET AJAX 4.0 client library&lt;/a&gt; is the &lt;font size="2" face="Courier New"&gt;Function.validateParameters()&lt;/font&gt; method. I say “new,” but it has really been there all along as a the private member &lt;font size="2" face="Courier New"&gt;Function._validateParams()&lt;/font&gt;. We all know that there is no such thing as public and private in JavaScript, but the accepted practice is that all members starting with an underscore (“_”) should be considered private and left untouched. You are free to call private member functions and access private member variables if you like, but doing so is bad for a number of reasons. First, it violates industry standard. Second, and most importantly, doing so is not supported by Microsoft. So if in a future release Microsoft suddenly decides to change the behavior of the private member to something unexpected, you won’t have anyone to blame but yourself. &lt;/p&gt;  &lt;p align="justify"&gt;As of Preview 4 of the ASP.NET AJAX 4.0 client library, the functionality has been exposed through the &lt;font size="2" face="Courier New"&gt;Function.validateParameters()&lt;/font&gt; method. I’m glad the folks at Microsoft have realized the value in making this feature public. Here’s how you can start using it today…&lt;/p&gt;  &lt;div align="justify"&gt;   &lt;pre class="brush: js; gutter: false;"&gt;Function.validateParameters(parameters, expectedParameters, validateParameterCount) &lt;/pre&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;&lt;strong&gt;&lt;font size="4"&gt;parameters&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p align="justify"&gt;The first argument is the list of the parameters that were actually passed to the JavaScript function. This can be easily accessed by calling the &lt;a href="http://www.sitepoint.com/blogs/2008/11/11/arguments-a-javascript-oddity/"&gt;arguments variable&lt;/a&gt;, which is local to every function.&lt;/p&gt;

&lt;div align="justify"&gt;
  &lt;pre class="brush: js; gutter: false; highlight: [2];"&gt;function doSomething(aString, aNumber) {
    var e = Function.validateParameters(arguments, [
        { name: &amp;quot;aString&amp;quot;, type: String },
        { name: &amp;quot;aNumber&amp;quot;, type: Number }
    ], false);
    if (e) throw e;
    // do something...    
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;&lt;strong&gt;&lt;font size="4"&gt;expectedParameters&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p align="justify"&gt;The second parameter is an array containing information about each expected parameter. There are several options you can use to specify what type of parameter is expected:&lt;/p&gt;

&lt;div align="justify"&gt;
  &lt;pre class="brush: js; gutter: false;"&gt;var e = Function.validateParameters(arguments, [
    { 
        name:              &amp;quot;name&amp;quot;,          // any string value
        type:              [expected type], // any native or custom JavaScript type
        integer:           [true|false],
        domElement:        [true|false],
        mayBeNull:         [true|false],
        optional:          [true|false],
        elementType:       [true|false],
        elementDomElement: [true|false],
        elementInteger:    [true|false],
        elementMayBeNull:  [true|false]
    }, ...]);&lt;/pre&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;&lt;u&gt;name&lt;/u&gt;: The name of the parameter. The name is not used in any validation, but is instead used for error reporting. If validation fails, the name value will be passed to the Error object returned from &lt;font size="2" face="Courier New"&gt;Function.validateParameters()&lt;/font&gt; to indicate which parameter was the culprit.&lt;/p&gt;

&lt;p align="justify"&gt;&lt;u&gt;type&lt;/u&gt;: The data type of the parameter. This can be a native JavaScript type, an ASP.NET AJAX client library type, or your own custom type.&lt;/p&gt;

&lt;div align="justify"&gt;
  &lt;pre class="brush: js; gutter: false; highlight: [3,12];"&gt;function sendMessage(message) {
    var e = Function.validateParameters(arguments, [
        { name: &amp;quot;message&amp;quot;, type: String }
    ], true);
    if (e) throw e;
    // send message...    
}
sendMessage('This is a test message');

function saveCustomer(customer) {
    var e = Function.validateParameters(arguments, [
        { name: &amp;quot;customer&amp;quot;, type: MyApp.Entities.Customer}
    ], true);
    if (e) throw e;
    // save customer...    
}
var customer = new MyApp.Entities.Customer();
saveCustomer(customer);&lt;/pre&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;&lt;u&gt;domElement&lt;/u&gt;: A boolean value indicating whether or not the parameter is a DOM element.&lt;/p&gt;

&lt;div align="justify"&gt;
  &lt;pre class="brush: js; gutter: false; highlight: [3];"&gt;function updateContent(container) {
    var e = Function.validateParameters(arguments, [
        { name: &amp;quot;container&amp;quot;, domElement: true }
    ], true);
    if (e) throw e;
    // update content...    
}
var divContainer = $get('container');
var nonExistingElement = $get('nothing');  // returns null
updateContent(divContainer);
updateContent(nonExistingElement);         // throws Sys.ArgumentException
updateContent('test');                     // throws Sys.ArgumentNullException&lt;/pre&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;&lt;u&gt;integer&lt;/u&gt;: A boolean value indicating whether or not the parameter is an integer. Only evaluated if the &lt;font size="2" face="Courier New"&gt;type&lt;/font&gt; option is set to &lt;font size="2" face="Courier New"&gt;Number&lt;/font&gt;.&lt;/p&gt;

&lt;pre class="brush: js; gutter: false; highlight: [13];"&gt;function updateAge(age) {
    var e = Function.validateParameters(arguments, [
        { name: &amp;quot;age&amp;quot;, type: Number }], 
    true);
    if (e) throw e;
    // update age...
}
updateAge(23.78);  // ok
updateAge(23);     // ok

function updateAge(age) {
    var e = Function.validateParameters(arguments, [
        { name: &amp;quot;age&amp;quot;, type: Number, integer: true }], 
    true);
    if (e) throw e;
    // update age...
}
updateAge(23.78)   // throws Sys.ArgumentOutOfRangeException
updateAge(23);     // legal&lt;/pre&gt;

&lt;p align="justify"&gt;&lt;u&gt;mayBeNull&lt;/u&gt;: A boolean value indicating whether or not the parameter may be null.&lt;/p&gt;

&lt;pre class="brush: js; gutter: false; highlight: [3];"&gt;function doSomething(aString) {
    var e = Function.validateParameters(arguments, [
        { name: &amp;quot;aString&amp;quot;, type: String, mayBeNull: true }], 
    true);
    if (e) throw e;
    // do something...
}
doSomething('');   // ok
doSomething(null); // ok
doSomething();     // throws Sys.ParameterCountException&lt;/pre&gt;

&lt;p align="justify"&gt;&lt;u&gt;optional&lt;/u&gt;: A boolean value indicating whether or not the parameter is optional.&lt;/p&gt;

&lt;pre class="brush: js; gutter: false;"&gt;function doSomething(aString) {
    var e = Function.validateParameters(arguments, [
        { name: &amp;quot;aString&amp;quot;, type: String, optional: true }], 
    true);
    if (e) throw e;
    // do something...
}
doSomething('');   // ok
doSomething(null); // throws Sys.ArgumentNullException
doSomething();     // ok&lt;/pre&gt;

&lt;p align="justify"&gt;&lt;u&gt;elementType&lt;/u&gt;: The data type expected for each element of an array parameter. This can be a native JavaScript type, an ASP.NET AJAX client library type, or your own custom type. Does not enforce any restriction on the array size.&lt;/p&gt;

&lt;pre class="brush: js; gutter: false; highlight: [3];"&gt;function doSomething(anArray) {
    var e = Function.validateParameters(arguments, [
        { name: &amp;quot;anArray&amp;quot;, type: Array, elementType: String }], 
    true);
    if (e) throw e;
    // do something...
}
doSomething([]);                // ok
doSomething(['test']);          // ok
doSomething(['one', 'two']);    // ok
doSomething(['one', 'two', 3]); // throws Sys.ArgumentTypeException
doSomething();                  // throws Sys.ParameterCountException&lt;/pre&gt;

&lt;p align="justify"&gt;&lt;u&gt;elementDomElement&lt;/u&gt;: A boolean value indicating whether or not each element in the array parameter is a DOM element. Does not enforce any restriction on the array size.&lt;/p&gt;

&lt;pre class="brush: js; gutter: false; highlight: [3];"&gt;function doSomething(anArray) {
    var e = Function.validateParameters(arguments, [
        { name: &amp;quot;anArray&amp;quot;, type: Array, elementDomElement: true }], 
    true);
    if (e) throw e;
    // do something...
}
doSomething([$get('container')]); // ok
doSomething(['test']);            // throws Sys.ArgumentException
doSomething();                    // throws Sys.ParameterCountException&lt;/pre&gt;

&lt;p align="justify"&gt;&lt;u&gt;elementInteger&lt;/u&gt;: A boolean value indicating whether or not each element in the array parameter is an integer. Only evaluated if the &lt;font size="2" face="Courier New"&gt;type&lt;/font&gt; option is set to &lt;font size="2" face="Courier New"&gt;Number&lt;/font&gt;. Does not enforce any restriction on the array size.&lt;/p&gt;

&lt;pre class="brush: js; gutter: false; highlight: [3];"&gt;function doSomething(anArray) {
    var e = Function.validateParameters(arguments, [
        { name: &amp;quot;anArray&amp;quot;, type: Array, elementType: Number, elementInteger: true }], 
    true);
    if (e) throw e;
    // do something...
}
doSomething([]);        // ok
doSomething([null]);    // throws ArgumentNullException
doSomething([1, 2, 3]); // ok
doSomething();          // throws ParameterCountException&lt;/pre&gt;

&lt;p align="justify"&gt;&lt;u&gt;elementMayBeNull&lt;/u&gt;: A boolean value indicating whether or not each element in the array parameter may be null. Does not enforce any restriction on the array size.&lt;/p&gt;

&lt;pre class="brush: js; gutter: false;  highlight: [3];"&gt;function doSomething(anArray) {
    var e = Function.validateParameters(arguments, [
        { name: &amp;quot;anArray&amp;quot;, type: Array, elementMayBeNull: true }], 
    true);
    if (e) throw e;
    // do something...
}
doSomething([]);                      // ok
doSomething([null, '']);              // ok
doSomething(['test', null, 'test']);  // ok
doSomething();                        // throws Sys.ParameterCountException&lt;/pre&gt;

&lt;p align="justify"&gt;&lt;u&gt;parameterArray&lt;/u&gt;: A boolean value indicating whether or not the parameter is a variable-length array. This option is helpful when you want to define a function with a required set of parameters and a variable number of trailing parameters.&amp;#160; A good example is the ASP.NET AJAX client library’s &lt;font size="2" face="Courier New"&gt;String.format()&lt;/font&gt;: &lt;/p&gt;

&lt;div align="justify"&gt;
  &lt;pre class="brush: js; gutter: false; highlight: [4];"&gt;String.format = function String$format(format, args) {
    var e = Function._validateParams(arguments, [
        {name: &amp;quot;format&amp;quot;, type: String},
        {name: &amp;quot;args&amp;quot;, mayBeNull: true, parameterArray: true}
    ]);
    if (e) throw e;
    return String._toFormattedString(false, arguments);
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;It expects a format parameter or type &lt;font size="2" face="Courier New"&gt;String&lt;/font&gt;, and then a variable number of arguments.&lt;/p&gt;

&lt;div align="justify"&gt;
  &lt;pre class="brush: js; gutter: false;"&gt;var name = &amp;quot;Kevin&amp;quot;, age = 28;
var formattedValue = String.format(&amp;quot;Name: {0}, Age: {1}&amp;quot;, name, age);&lt;/pre&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;There are some peculiarities that you should be aware of when using several mutually exclusive parameter options (domElement, integer, etc) at the same time. Specifically, there is an order of precedence when evaluating the parameter rules and certain combinations of options may cause unexpected results. However, those details will have to wait for another post.&lt;/p&gt;

&lt;p align="justify"&gt;&lt;strong&gt;&lt;font size="4"&gt;validateParameterCount&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p align="justify"&gt;The third argument to &lt;font size="2" face="Courier New"&gt;Function.validateParameters()&lt;/font&gt; indicates whether or not to explicitly validate the parameter count. JavaScript allows you to pass in a different number of parameters than expected&amp;#160; by a function.&lt;/p&gt;

&lt;div align="justify"&gt;
  &lt;pre class="brush: js; gutter: false;"&gt;function doSomething(aString, aNumber) {
    // do something...    
}

// both of the following function calls are legal
doSomething('test');          // aString = 'test', aNumber = undefined
doSomething('test', 1, 2, 3); // aString = 'test', aNumber = 1&lt;/pre&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;Passing fewer parameters than expected by a JavaScript function results in the extra parameters being &lt;font size="2" face="Courier New"&gt;undefined&lt;/font&gt;. Passing more parameters than expected is also legal, but the extra parameter values are only accessible by referencing the proper index in the local &lt;font size="2" face="Courier New"&gt;arguments&lt;/font&gt; variable. &lt;/p&gt;

&lt;p align="justify"&gt;Using the &lt;font size="2" face="Courier New"&gt;validateParameterCount&lt;/font&gt; option, you can ensure that the correct number of parameters is present. &lt;/p&gt;

&lt;div align="justify"&gt;
  &lt;pre class="brush: js; gutter: false;"&gt;function doSomething(aString) {
    var e = Function.validateParameters(arguments, [{ name: &amp;quot;aString&amp;quot; }], true);
    if (e) throw e;
    // do something...    
}
doSomething('test'); // ok
doSomething(25);     // ok
doSomething();       // throws a Sys.ParameterCountException&lt;/pre&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;The first two calls to &lt;font size="2" face="Courier New"&gt;doSomething()&lt;/font&gt; are perfectly legal. Since no parameter type was specified, the only validation that occurs is the parameter count. The third call will cause &lt;font size="2" face="Courier New"&gt;Function.validateParameters()&lt;/font&gt; to return an &lt;font size="2" face="Courier New"&gt;Error.parameterCount&lt;/font&gt; exception, which will be thrown by the calling function.&lt;/p&gt;

&lt;p align="justify"&gt;Since the ASP.NET AJAX client library validates the parameters passed in to &lt;font size="2" face="Courier New"&gt;Function.validateParameters()&lt;/font&gt;, you cannot omit the first two. However, the third is optional and will default to &lt;font size="2" face="Courier New"&gt;true&lt;/font&gt; if unspecified.&lt;/p&gt;

&lt;p align="justify"&gt;It is important to note that when using the &lt;font size="2" face="Courier New"&gt;validateParameterCount&lt;/font&gt; option in conjunction with the &lt;font size="2" face="Courier New"&gt;parameterArray&lt;/font&gt; option, the enforced minimum number of parameters will be the number of parameters preceding the one with the &lt;font size="2" face="Courier New"&gt;parameterArray&lt;/font&gt; option in the &lt;font size="2" face="Courier New"&gt;expectedParameters&lt;/font&gt; array.&lt;/p&gt;

&lt;div align="justify"&gt;
  &lt;pre class="brush: js; gutter: false;"&gt;// requires a minimum of 2 parameters, no maximum
function doSomething(aString, aNumber, params) {
    var e = Function.validateParameters(arguments, [
        { name: &amp;quot;aString&amp;quot;, type: String },
        { name: &amp;quot;aNumber&amp;quot;, type: Number },
        { name: &amp;quot;params&amp;quot;, parameterArray: true  }
    ], true);
    if (e) throw e;
    // do something...    
}

// requires a minimum of 1 parameter, no maximum
function doSomethingElse(aString, params) {
    var e = Function.validateParameters(arguments, [
        { name: &amp;quot;aString&amp;quot;, type: String },
        { name: &amp;quot;params&amp;quot;, parameterArray: true  }
    ], true);
    if (e) throw e;
    // do something...    
}

doSomething('test');                       // throws a Sys.ParameterCountException
doSomething('test', 123);                  // ok
doSomething('test', 123, 'testing', 123);  // ok
doSomething();                             // throws a Sys.ParameterCountException
doSomethingElse('test');                   // ok
doSomethingElse('test', 123, 123);         // ok&lt;/pre&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;&lt;strong&gt;&lt;font size="4"&gt;Wrap up&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p align="justify"&gt;Due to its dynamic nature and language-specific peculiarities, type-checking in JavaScript is usually a cumbersome task. Fortunately, the folks at Microsoft have abstracted those details away into a tidy little function call, making it easier than ever to enforce type safety on our functions. Since it is used to perform type-checking throughout the entire ASP.NETAJAX client library, I think it is safe to assume that &lt;font size="2" face="Courier New"&gt;Function.validateParameters()&lt;/font&gt; performs fairly well. However, I haven’t done any performance testing myself so I recommend testing it in your own applications before using it extensively.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.myviewstate.net%2fblog%2fpost%2f2009%2f06%2f23%2fASPNET-AJAX-Type-safe-parameters.aspx"&gt;&lt;img border="0" alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.myviewstate.net%2fblog%2fpost%2f2009%2f06%2f23%2fASPNET-AJAX-Type-safe-parameters.aspx" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kevinbabcock/~4/okjNgTDzt8k" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/kevinbabcock/~3/okjNgTDzt8k/post.aspx</link>
      <author>Kevin Babcock</author>
      <comments>http://www.myviewstate.net/blog/post/2009/06/23/ASPNET-AJAX-Type-safe-parameters.aspx#comment</comments>
      <guid isPermaLink="false">http://www.myviewstate.net/blog/post.aspx?id=2c7f9388-5154-4751-8da0-b486131dc7c2</guid>
      <pubDate>Tue, 23 Jun 2009 01:49:52 -0400</pubDate>
      <category>Web Development</category>
      <dc:publisher>Kevin Babcock</dc:publisher>
      <pingback:server>http://www.myviewstate.net/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.myviewstate.net/blog/post.aspx?id=2c7f9388-5154-4751-8da0-b486131dc7c2</pingback:target>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://www.myviewstate.net/blog/trackback.axd?id=2c7f9388-5154-4751-8da0-b486131dc7c2</trackback:ping>
      <wfw:comment>http://www.myviewstate.net/blog/post/2009/06/23/ASPNET-AJAX-Type-safe-parameters.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.myviewstate.net/blog/syndication.axd?post=2c7f9388-5154-4751-8da0-b486131dc7c2</wfw:commentRss>
    <feedburner:origLink>http://www.myviewstate.net/blog/post.aspx?id=2c7f9388-5154-4751-8da0-b486131dc7c2</feedburner:origLink></item>
    <item>
      <title>Shhhh…You’ll wake the baby!</title>
      <description>&lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 5px 5px; display: inline; border-top: 0px; border-right: 0px" title="baby" border="0" alt="baby" align="right" src="http://www.myviewstate.net/blog/image.axd?picture=baby.jpg" width="330" height="327" /&gt; &lt;/p&gt;  &lt;p&gt;The baby just fell asleep, the wife is on a plane to California, and I’ve got some free time. Never mind the big pile of laundry, the dirty dishes, the overgrown lawn, or the growing list of unwatched “Law &amp;amp; Order” episodes on the DVR. It’s time to do some writing!&lt;/p&gt;  &lt;p&gt;I’ve been quiet lately. Not for lack of things to write about, but due to a flurry of long work days, a teething baby, and even a weekend vacation. The content is coming, I promise! I know, I know…another blog goes silent for several weeks, then the author pops in with an explanation and promises of posts to come. Well, I won’t promise anything except that I’ve got a huge backlog of topics I want to cover and not enough time to write about them all. There are already a few in the pipeline, but they’ll trickle out as time allows. &lt;/p&gt;  &lt;p&gt;I hope you’ll stay tuned.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/kevinbabcock/~4/miyqvRATOvE" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/kevinbabcock/~3/miyqvRATOvE/post.aspx</link>
      <author>Kevin Babcock</author>
      <comments>http://www.myviewstate.net/blog/post/2009/06/22/Shhhhe280a6Youe28099ll-wake-the-baby!.aspx#comment</comments>
      <guid isPermaLink="false">http://www.myviewstate.net/blog/post.aspx?id=884f4d85-3b22-4869-a55e-2682e616451f</guid>
      <pubDate>Mon, 22 Jun 2009 19:26:19 -0400</pubDate>
      <category>General</category>
      <dc:publisher>Kevin Babcock</dc:publisher>
      <pingback:server>http://www.myviewstate.net/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.myviewstate.net/blog/post.aspx?id=884f4d85-3b22-4869-a55e-2682e616451f</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://www.myviewstate.net/blog/trackback.axd?id=884f4d85-3b22-4869-a55e-2682e616451f</trackback:ping>
      <wfw:comment>http://www.myviewstate.net/blog/post/2009/06/22/Shhhhe280a6Youe28099ll-wake-the-baby!.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.myviewstate.net/blog/syndication.axd?post=884f4d85-3b22-4869-a55e-2682e616451f</wfw:commentRss>
    <feedburner:origLink>http://www.myviewstate.net/blog/post.aspx?id=884f4d85-3b22-4869-a55e-2682e616451f</feedburner:origLink></item>
  </channel>
</rss>
