<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.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>Jon Skeet: Coding Blog : CSharpDev, LINQ, CSharpDevCenter</title><link>http://msmvps.com/blogs/jon_skeet/archive/tags/CSharpDev/LINQ/CSharpDevCenter/default.aspx</link><description>Tags: CSharpDev, LINQ, CSharpDevCenter</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Designing LINQ operators</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/01/23/designing-linq-operators.aspx</link><pubDate>Fri, 23 Jan 2009 23:40:39 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1665190</guid><dc:creator>skeet</dc:creator><slash:comments>16</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1665190</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1665190</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/01/23/designing-linq-operators.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve started a small project (I&amp;#39;ll post a link when I&amp;#39;ve actually got something worthwhile to show) with some extra LINQ operators in - things which I think are missing from LINQ to Objects, basically. (I hope to include many of the ideas from an &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2008/10/23/what-other-enumerable-extension-methods-would-you-like-to-see.aspx"&gt;earlier blog post&lt;/a&gt;.) That, and a few Stack Overflow questions where I&amp;#39;ve effectively written extra LINQ operators and compared them with other solutions, have made me think about the desirable properties of a LINQ operator - or at least the things you should think about when implementing one. My thoughts so far:&lt;/p&gt; &lt;h3&gt;Lazy/eager execution&lt;/h3&gt; &lt;p&gt;If you&amp;#39;re returning a sequence (i.e. another IEnumerable&amp;lt;T&amp;gt; or similar) the execution should almost certainly be lazy, but the parameter checking should be eager. Unfortunately with the &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2008/03/02/c-4-idea-iterator-blocks-and-parameter-checking.aspx"&gt;limitations of the (otherwise wonderful) C# iterator blocks&lt;/a&gt;, this usually means breaking the method into two, like this:&lt;/p&gt; &lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;static&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; Where(&lt;span class="Keyword"&gt;this&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; source,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Func&amp;lt;T, &lt;span class="ValueType"&gt;bool&lt;/span&gt;&amp;gt; predicate)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="InlineComment"&gt;// Eagerly executed&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;if&lt;/span&gt; (source == &lt;span class="Keyword"&gt;null&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;throw&lt;/span&gt;&amp;nbsp;&lt;span class="Keyword"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span class="String"&gt;&amp;quot;source&amp;quot;&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;if&lt;/span&gt; (predicate == &lt;span class="Keyword"&gt;null&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;throw&lt;/span&gt;&amp;nbsp;&lt;span class="Keyword"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span class="String"&gt;&amp;quot;predicate&amp;quot;&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;return&lt;/span&gt; WhereImpl(source, predicate);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;static&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; WhereImpl(IEnumerable&amp;lt;T&amp;gt; source,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Func&amp;lt;T, &lt;span class="ValueType"&gt;bool&lt;/span&gt;&amp;gt; predicate)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="InlineComment"&gt;// Lazily executed&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;foreach&lt;/span&gt; (T element &lt;span class="Statement"&gt;in&lt;/span&gt; source)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;if&lt;/span&gt; (predicate(element))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;yield&lt;/span&gt;&amp;nbsp;&lt;span class="Statement"&gt;return&lt;/span&gt; element;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;Obviously aggregates and conversions (Max, ToList etc) are generally eager anyway, within normal LINQ to Objects. (Just about everything in Push LINQ is lazy. They say pets look like their owners...)&lt;/p&gt; &lt;h3&gt;Streaming/buffering&lt;/h3&gt; &lt;p&gt;One of my favourite features of LINQ to Objects (and one which doesn&amp;#39;t get nearly the publicity of deferred execution) is that many of the operators &lt;em&gt;stream&lt;/em&gt; the data. In other words, they only consume data when they absolutely have to, and they yield data as soon as they can. This means you can process vast amounts of data with very little memory usage, so long as you use the right operators. Of course, not every operator can stream (reversing requires buffering, for example) but where it&amp;#39;s possible, it&amp;#39;s really handy.&lt;/p&gt; &lt;p&gt;Unfortunately, the streaming/buffering nature of operators isn&amp;#39;t well documented in MSDN - and sometimes it&amp;#39;s completely wrong. As I&amp;#39;ve &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2008/09/09/logging-enumeration-flow.aspx"&gt;noted before&lt;/a&gt;, the &lt;a href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.intersect.aspx"&gt;docs for Enumerable.Intersect&lt;/a&gt; claim that it reads the &lt;em&gt;whole&lt;/em&gt; of both sequences (&lt;em&gt;first&lt;/em&gt; then &lt;em&gt;second&lt;/em&gt;) before yielding any data. In fact it reads and buffers the whole of &lt;em&gt;second&lt;/em&gt;, then streams &lt;em&gt;first&lt;/em&gt;, yielding intersecting elements as it goes. I strongly encourage new LINQ operators to document their streaming/buffering behaviour (accurately!). This will limit future changes in the implementation admittedly (Intersect can be implemented in a manner where both inputs are streamed, for example) but in this case I think the extra guarantees provided by the documentation make up for that restriction.&lt;/p&gt; &lt;h3&gt;Once-only evaluation&lt;/h3&gt; &lt;p&gt;When I said that reversing requires buffering earlier on, I was sort of lying. Here&amp;#39;s an implementation of Reverse which doesn&amp;#39;t buffer any data anywhere:&lt;/p&gt; &lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Modifier"&gt;static&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; StreamingReverse&amp;lt;T&amp;gt;(&lt;span class="Keyword"&gt;this&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; source)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="InlineComment"&gt;// Error checking omitted for brevity&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="ValueType"&gt;int&lt;/span&gt; count = source.Count();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; i = count-1; i &amp;gt;= 0; i--)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Statement"&gt;yield&lt;/span&gt;&amp;nbsp;&lt;span class="Statement"&gt;return&lt;/span&gt; source.ElementAt(i);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;} &lt;/div&gt; &lt;p&gt;If we assume we can read the sequence as often as we like, then we never need to buffer anything - just treat it as a random-access list. I hope I don&amp;#39;t have to tell you that&amp;#39;s a really, &lt;em&gt;really&lt;/em&gt; bad idea. Leaving aside the blatant inefficiency even for sequences like lists which are cheap to iterate over, some sequences are inherently once-only (think about reading from a network stream) and some are inherently costly to iterate over (think about lines in a big log file - or the result of an ordering).&lt;/p&gt; &lt;p&gt;I suspect that developers using LINQ operators &lt;em&gt;assume&lt;/em&gt; that they&amp;#39;ll only read the input data once. That&amp;#39;s a good assumption - wherever possible, we ought to make sure that it&amp;#39;s correct, and if we absolutely can&amp;#39;t help evaluating a sequence twice (and I can&amp;#39;t remember any times when I&amp;#39;ve really wanted to do that) we should document it in large, friendly letters.&lt;/p&gt; &lt;h3&gt;Mind your complexity&lt;/h3&gt; &lt;p&gt;In some ways, this falls out of &amp;quot;try to stream, and try to only read once&amp;quot; - if you&amp;#39;re not storing any data and you&amp;#39;re only reading each item once, it&amp;#39;s quite hard to come up with an operator which &lt;em&gt;isn&amp;#39;t&lt;/em&gt; just O(n) for a single sequence. It is worth thinking about though - particularly as most of the LINQ operators &lt;em&gt;can&lt;/em&gt; work with large amounts of data. For example, to find the smallest element in a sequence you can &lt;em&gt;either&lt;/em&gt; sort the whole sequence and take the first element of the result &lt;em&gt;or&lt;/em&gt; you can keep track of a &amp;quot;current minimum&amp;quot; and iterate through the whole sequence. Clearly the latter saves a lot of complexity (and doesn&amp;#39;t require buffering) - so don&amp;#39;t just take the first idea that comes into your head. (Or at least, start with that and then think how you could improve it.)&lt;/p&gt; &lt;p&gt;Again, documenting the complexity of the operator is a good idea, and call particular attention to anything which is &lt;em&gt;unintuitively&lt;/em&gt; expensive.&lt;/p&gt; &lt;h3&gt;Conclusion&lt;/h3&gt; &lt;p&gt;Okay, so there&amp;#39;s nothing earth-shattering here. But the more I use LINQ to answer Stack Overflow questions, and the more I invent new operators in the &lt;em&gt;spirit&lt;/em&gt; of the existing ones, the more powerful I think it is. It&amp;#39;s amazing how powerful it can be, and how ridiculously simple the code (sometimes) looks afterwards. It&amp;#39;s not like the operator implementation is usually hard, either - it&amp;#39;s just a matter of thinking of the right concepts. I&amp;#39;m going to try to follow these principles when I implement my extra operator library, and I hope you&amp;#39;ll bear them in mind too, should you ever feel that LINQ to Objects doesn&amp;#39;t have &lt;em&gt;quite&lt;/em&gt; the extension method you need...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1665190" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/CSharpDevCenter/default.aspx">CSharpDevCenter</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/CSharpDev/default.aspx">CSharpDev</category></item><item><title>You don't have to use query expressions to use LINQ</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/01/07/you-don-t-have-to-use-query-expressions-to-use-linq.aspx</link><pubDate>Wed, 07 Jan 2009 17:32:24 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1658790</guid><dc:creator>skeet</dc:creator><slash:comments>18</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1658790</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1658790</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/01/07/you-don-t-have-to-use-query-expressions-to-use-linq.aspx#comments</comments><description>&lt;p&gt;LINQ is clearly gaining a fair amount of traction, given the number of posts I see about it on &lt;a href="http://stackoverflow.com"&gt;Stack Overflow&lt;/a&gt;. However, I&amp;#39;ve noticed an interesting piece of coding style: a lot of developers are using query expressions for &lt;em&gt;every&lt;/em&gt; bit of LINQ they write, however trivial.&lt;/p&gt; &lt;p&gt;Now, don&amp;#39;t get the wrong idea - I love query expressions as a helpful piece of syntactic sugar. For instance, I&amp;#39;d always pick the query expression form over the &amp;quot;dot notation&amp;quot; form for something like this:&lt;/p&gt; &lt;div class="code"&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; query = &lt;span class="Linq"&gt;from&lt;/span&gt; file &lt;span class="Statement"&gt;in&lt;/span&gt; Directory.GetFiles(logDirectory, &lt;span class="String"&gt;&amp;quot;*.log&amp;quot;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Linq"&gt;from&lt;/span&gt; line &lt;span class="Statement"&gt;in&lt;/span&gt;&amp;nbsp;&lt;span class="Keyword"&gt;new&lt;/span&gt; LineReader(file)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Linq"&gt;let&lt;/span&gt; entry = &lt;span class="Keyword"&gt;new&lt;/span&gt; LogEntry(line)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Linq"&gt;where&lt;/span&gt; entry.Severity == Severity.Error&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Linq"&gt;select&lt;/span&gt; file + &lt;span class="String"&gt;&amp;quot;: &amp;quot;&lt;/span&gt; + entry.Message; &lt;/div&gt; &lt;p&gt;(Yes, it&amp;#39;s yet another log entry example - it&amp;#39;s one of my favourite demos of LINQ, and particularly Push LINQ.) The equivalent code using just the extension methods would be pretty ugly, especially given the various range variables and transparent identifiers involved.&lt;/p&gt; &lt;p&gt;However, look at &lt;em&gt;these&lt;/em&gt; two queries instead:&lt;/p&gt; &lt;div class="code"&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; query = &lt;span class="Linq"&gt;from&lt;/span&gt; person &lt;span class="Statement"&gt;in&lt;/span&gt; people&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Linq"&gt;where&lt;/span&gt; person.Salary &amp;gt; 10000m&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Linq"&gt;select&lt;/span&gt; person;&lt;br /&gt;&lt;br /&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; dotNotation = people.Where(person =&amp;gt; person.Salary &amp;gt; 10000m); &lt;/div&gt; &lt;p&gt;In this case, we&amp;#39;re just making a single method call. Why bother with three lines of query expression? If the query becomes more complicated later, it can easily be converted into a query expression at that point. The two queries are &lt;em&gt;exactly&lt;/em&gt; the same, even though the syntax is different.&lt;/p&gt; &lt;p&gt;My guess is that there&amp;#39;s a &amp;quot;black magic&amp;quot; fear of LINQ - many developers know how to write query expressions, but aren&amp;#39;t confident about what they&amp;#39;re converted into (or even the basics of what the translation process is like in the first place). Most of the C# 3.0 and LINQ books that I&amp;#39;ve read &lt;em&gt;do&lt;/em&gt; cover query expression translation to a greater or lesser extent, but it&amp;#39;s rarely given much prominence.&lt;/p&gt; &lt;p&gt;I suspect the black magic element is reinforced by the inherent &amp;quot;will it work?&amp;quot; factor of LINQ to SQL - you get to write the query in your favourite language, but you may well not be confident in it working until you&amp;#39;ve tried it; there will always be plenty of little gotchas which can&amp;#39;t be picked up at compile time. With LINQ to Objects, there&amp;#39;s a lot more certainty (at least in my experience). However, the query expression translation &lt;em&gt;shouldn&amp;#39;t&lt;/em&gt; be part of what developers are wary of. It&amp;#39;s clearly defined in the spec (not that I&amp;#39;m suggesting that all developers should learn it via the spec) and benefits from being relatively dumb and therefore easy to predict.&lt;/p&gt; &lt;p&gt;So next time you&amp;#39;re writing a query expression, take a look at it afterwards - if it&amp;#39;s simple, try writing it without the extra syntactic sugar. It may just be sweet enough on its own.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1658790" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/CSharpDevCenter/default.aspx">CSharpDevCenter</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/CSharpDev/default.aspx">CSharpDev</category></item><item><title>DeveloperDeveloperDeveloper: Registration now open (hurry!)</title><link>http://msmvps.com/blogs/jon_skeet/archive/2008/10/22/developerdeveloperdeveloper-registration-now-open-hurry.aspx</link><pubDate>Wed, 22 Oct 2008 09:53:34 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1651598</guid><dc:creator>skeet</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1651598</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1651598</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2008/10/22/developerdeveloperdeveloper-registration-now-open-hurry.aspx#comments</comments><description>&lt;p&gt;The &lt;a href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032393874&amp;amp;Culture=en-GB"&gt;registration page for DeveloperDeveloperDeveloper Day 2008&lt;/a&gt; (Reading, November 22nd) is now open. In the past this has been heavily oversubscribed, so if you want to come you&amp;#39;ll need to register quickly.&lt;/p&gt; &lt;p&gt;I&amp;#39;ve got a speaking slot in the afternoon: implementing LINQ to Objects in 60 minutes. As always, I&amp;#39;m very much looking forward to it.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1651598" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/CSharpDevCenter/default.aspx">CSharpDevCenter</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/CSharpDev/default.aspx">CSharpDev</category></item></channel></rss>