<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6936260</id><updated>2012-01-10T15:00:36.831Z</updated><category term='C#'/><category term='jPod'/><category term='.Net 2.0'/><category term='JQuery'/><category term='Vista'/><category term='Firefox'/><category term='Agile'/><category term='Extension Methods'/><category term='Comment'/><category term='Web Services'/><category term='Coupland'/><category term='Xbox'/><category term='OpenOffice'/><category term='VB.Net'/><category term='Ubuntu'/><category term='YouTube'/><category term='Java'/><category term='CaveIn'/><category term='Refactoring'/><category term='XNA'/><category term='Shuttle'/><title type='text'>Ian Dykes</title><subtitle type='html'>A mixture of technical and not-so-technical discussions, gaming, programming, writing, life outside permanent employment.  My new and improved blog space.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>26</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6936260.post-6993461088191231854</id><published>2010-10-07T16:53:00.008+01:00</published><updated>2010-10-07T17:29:19.520+01:00</updated><title type='text'>Install Python 2.6 on ReadyNAS NV+</title><content type='html'>&lt;div&gt;Just a few steps that worked for me.  I can't be certain all the dependencies are listed here as I've been trying different things.  If you come across anything that doesn't work let me know and I'll try to think if I've missed anything out.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you're trying to install Python onto a ReadyNAS you'll find that the version you can get with "apt-get install python" will be around 2.3.something.  If you need a later version you need to build it from source yourself.  I only needed 2.6 and I found examples of other people being successful with building that version, so I haven't tried anything newer.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The instructions that follow are mainly from a post on the ReadyNAS forums and an article linked from that post.  These may contain all the information you require without me setting out the steps again:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.readynas.com/forum/viewtopic.php?f=35&amp;amp;t=35447&amp;amp;hilit=readynas+python+2.6&amp;amp;sid=9b8af84c15791ff732c7eb4fe7bd2d28"&gt;Trying to install Python 2.6 on DUO&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.thibernet.com/442-install-sabnzbd-on-a-readynas-duo"&gt;Install SABnzbd+ on a ReadyNas Duo&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Ignore the fact that both of these are targeted at the DUO, the instructions work for an NV+ as well.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The instructions assume you have already installed the ToggleSSH, EnableRootSSH and APT addons (all listed under the&lt;a href="http://www.readynas.com/?page_id=617"&gt; ReadyNAS addons&lt;/a&gt;), and you know how to SSH to your NAS.  I'm connecting from a Windows 7 box, so I just use &lt;a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/"&gt;PuTTY&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;SSH to your NAS&lt;/li&gt;&lt;li&gt;Install the dependencies to build Python:&lt;ul&gt;&lt;li&gt;apt-get update&lt;/li&gt;&lt;li&gt;apt-get install libc6-dev&lt;/li&gt;&lt;li&gt;apt-get install gcc&lt;/li&gt;&lt;li&gt;apt-get install gdb&lt;/li&gt;&lt;li&gt;apt-get install libtag1-dev&lt;/li&gt;&lt;li&gt;apt-get install uuid-dev&lt;/li&gt;&lt;li&gt;apt-get install libssl-dev&lt;/li&gt;&lt;li&gt;apt-get install zlibc&lt;/li&gt;&lt;li&gt;apt-get install zlib1g-dev&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Make a directory to save the source to:&lt;ul&gt;&lt;li&gt;mkdir /root/src/&lt;/li&gt;&lt;li&gt;cd /root/src/&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Patch the "uniq" program (the wget command should be on 1 line, and note the dot at the end of the dpkg-deb command):&lt;ul&gt;&lt;li&gt;wget ftp://ftp.gnome.org/cdimage/snapshot/Debian/pool/main/c/coreutils/coreutils_5.2.1-2_sparc.deb&lt;/li&gt;&lt;li&gt;dpkg-deb -x coreutils_5.2.1-2_sparc.deb .&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Build Python:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;wget http://www.python.org/ftp/python/2.6.6/Python-2.6.6.tgz&lt;/li&gt;&lt;li&gt;gzip -d Python-2.6.6.tgz&lt;/li&gt;&lt;li&gt;tar xf Python-2.6.6.tar&lt;/li&gt;&lt;li&gt;cd Python-2.6.6&lt;/li&gt;&lt;li&gt;./configure --build=sparc-linux&lt;/li&gt;&lt;li&gt;make&lt;/li&gt;&lt;li&gt;make install&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;div&gt;Be aware that the last 3 commands in step 5 each take quite a while to complete.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;And that's it.  "python --version" should give "Python 2.6.6".&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-6993461088191231854?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/6993461088191231854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=6993461088191231854' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/6993461088191231854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/6993461088191231854'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2010/10/install-python-26-on-readynas-nv.html' title='Install Python 2.6 on ReadyNAS NV+'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-1980094829035830134</id><published>2008-11-22T16:24:00.003Z</published><updated>2008-11-22T17:27:13.386Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><title type='text'>Agile Fail?</title><content type='html'>&lt;a href="http://developers.slashdot.org/"&gt;Slashdot&lt;/a&gt; has had links to &lt;a href="http://www.cio.com/article/464169/When_Agile_Projects_Go_Bad"&gt;When Agile Projects Go Bad&lt;/a&gt; at &lt;a href="http://www.cio.com/"&gt;cio.com&lt;/a&gt;, and &lt;a href="http://jamesshore.com/Blog/"&gt;James Shore&lt;/a&gt;'s post on &lt;a href="http://jamesshore.com/Blog/The-Decline-and-Fall-of-Agile.html"&gt;The Decline and Fall of Agile&lt;/a&gt; this past week, and it's raised a couple of interesting points for me--mainly concerning the manner in which it is adopted in a business.&lt;br /&gt;&lt;br /&gt;The CIO article opens with a piece describing how most people aquire new skills:&lt;br /&gt;&lt;blockquote&gt;In the first stage, people need to follow a recipe. In the second stage, you say 'That's all very nice, but I need more,' so you go off and collect recipes and ideas and techniques. And in the final stage—if you ever get there—is a level of fluency and intuitiveness where you can't say what you're doing, but you kind of borrow and blend.&lt;/blockquote&gt;Introducing Agile as a methodology tend to lead to people in the beginning conforming to a checklist culture.  The article then goes onto describe why this almost always has a negative impact on the process of building software.&lt;br /&gt;&lt;br /&gt;Some people just assume that by incorporating the practices defined within a particular Agile methodology that makes their business agile. Anyone who has been within a team where this has happened can quite clearly say this is not the case: Weekly releases? Check.  Pair programming? Check.  Test driven development? Check. Requirements as stories? Check.  How does going through the motions of applying these techniques lead to a better product?&lt;br /&gt;&lt;br /&gt;Answer: it doesn't.  I'm being quite absolute on this: if you're in a team that claims to be "agile" just because you are using some techniques you read in &lt;a href="http://books.google.co.uk/books?id=G8EL4H4vf7UC&amp;amp;dq=extreme+Programming+explained&amp;amp;pg=PP1&amp;amp;ots=j7uKuuhRun&amp;amp;source=bn&amp;amp;sig=Uy8G9UTHKV3Vwwi0b2LClDIix2c&amp;amp;hl=en&amp;amp;sa=X&amp;amp;oi=book_result&amp;amp;resnum=4&amp;amp;ct=result"&gt;Extreme Programming Explained&lt;/a&gt; then think again.&lt;br /&gt;&lt;br /&gt;Agile is a mindset you have to get into.  It's about trust and professionalism.  It's about seeing a problem as a series of stages, and tackling each one separately.  It's about communicating with your team and customers constantly.  It's about change.&lt;br /&gt;&lt;br /&gt;It's not about processes, and yet the processes have become the poster children for the entire movement.  Read the original &lt;a href="http://agilemanifesto.org/"&gt;Manifesto for Agile Software Development&lt;/a&gt;.  Read the &lt;a href="http://agilemanifesto.org/principles.html"&gt;Principles behind the Agile Manifesto&lt;/a&gt;.  There are no concrete techniques there at all.&lt;br /&gt;&lt;br /&gt;These ideas are what Agile is about, but its abstract nature is proving to be its downfall.  By being so abstract people bought in to the likes of &lt;a href="http://en.wikipedia.org/wiki/Extreme_Programming"&gt;XP&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Scrum_%28development%29"&gt;Scrum&lt;/a&gt;, where techniques were laid out.  And it's always the techniques that are going to take precedence over ideas.&lt;br /&gt;&lt;br /&gt;You can see that members of a team are pair programming.  You can monitor the amount of tests that developers are writing.  You can see requirements listed in story form.  But how do you monitor Agile's ideas?&lt;br /&gt;&lt;br /&gt;How do you tell if your team is motivated?  How do you tell if you team is self-organised? How do you tell if your team is keeping a constant pace?  These things are much harder to keep track of, but they stand at the heart of what pure Agile is about.&lt;br /&gt;&lt;br /&gt;And it's this that leads some people to believe that Agile is a failure.  In many ways it is, and I won't sit here and defend some implementations of it, but at its heart the set principles are sound.&lt;br /&gt;&lt;br /&gt;But it's not for everyone.  For Agile to make an impact you need a good team.  A trusted team with experience and who aren't too jaded to try new things.  A team that communicates, and where mistakes aren't chastised but taken in as just another problem to solve.&lt;br /&gt;&lt;br /&gt;Communication and team work are key to making a success with Agile.  It takes a good team to pull it off, I admit that.  Some teams won't thrive under its ideals, but when you put the right people together it gives them all the help they need.&lt;br /&gt;&lt;br /&gt;Just don't get too focused on the techniques you read about.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-1980094829035830134?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/1980094829035830134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=1980094829035830134' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/1980094829035830134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/1980094829035830134'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/11/agile-fail.html' title='Agile Fail?'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-2820565032535838653</id><published>2008-11-16T21:42:00.002Z</published><updated>2008-11-16T22:40:03.165Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='JQuery'/><title type='text'>JQuery - How Javascript should be</title><content type='html'>I go for months without posting and then drop 2 in one night...&lt;br /&gt;&lt;br /&gt;Let me first get something straight: I'm a focused lazy developer.  If there's something already written that I can use to solve a problem I'll use it.  As long as it's half decent and does what I need.  But this has a flip side in that I code my own stuff with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;reusability&lt;/span&gt; in mind.  Why spend hours solving a problem only to revisit it in another project a month down the line?&lt;br /&gt;&lt;br /&gt;So I must say that for a long time I didn't really get Javascript.  There didn't seem to be many opportunities for code reuse: each animation or validation check I did seemed wholly connected to one particular purpose.  I struggled to generalise my solutions to enough of a degree so that they could be reused.&lt;br /&gt;&lt;br /&gt;The impact of this was that I &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;shied&lt;/span&gt; away from Javascript whenever I could: so when Microsoft came along with the &lt;a href="http://www.asp.net/ajax/"&gt;AJAX Toolkit&lt;/a&gt; I was in heaven.  Here was a collection of cool controls I could just drop onto a form and get a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;popup&lt;/span&gt; div, or a water mark on a text box, or a whole bunch of other stuff.&lt;br /&gt;&lt;br /&gt;But at the back of my mind I couldn't help thinking this was all overkill.  If I want a div to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;popup&lt;/span&gt; when I click a link, surely all I need is a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;CSS&lt;/span&gt; style on it, and swap the display style from javascript?  So why have that as a control?  Simplicity of implementation.  It's easy.  The lazy part of me liked that.&lt;br /&gt;&lt;br /&gt;The focused part didn't.  The focused part wanted to come up with a library that contained a load of these common functions so I didn't have to re-invent them on every project.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jquery.com/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;JQuery&lt;/span&gt;&lt;/a&gt; does just that, and more.  I won't pollute the web with yet another &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;JQuery&lt;/span&gt; tutorial (go see &lt;a href="http://www.west-wind.com/presentations/jQuery/default.aspx"&gt;Rick &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Strahl&lt;/span&gt;&lt;/a&gt; if you want one) but I will say this.  If you're a developer who likes to &lt;a href="http://en.wikipedia.org/wiki/Separation_of_concerns"&gt;separate their concerns&lt;/a&gt;, take a look.&lt;br /&gt;&lt;br /&gt;We're all familiar with layering applications: &lt;a href="http://en.wikipedia.org/wiki/Model-view-controller"&gt;View-Model-Controller&lt;/a&gt;, Interface-Business-Data access-- it all amounts to the same thing.  We're separating each element of the application so that we have structure.  Structure eases maintainability.  It removes &lt;a href="http://www.amazon.co.uk/Refactoring-Improving-Existing-Addison-Wesley-Technology/dp/0201485672"&gt;bad smells&lt;/a&gt;.  It increases &lt;a href="http://en.wikipedia.org/wiki/Orthogonality"&gt;orthogonality&lt;/a&gt;.  For want of a better term--It Just Feels Right.&lt;br /&gt;&lt;br /&gt;So why stick Javascript code in HTML?  Isn't that polluting the structure of the document with behaviour?&lt;br /&gt;&lt;br /&gt;Linking to a &lt;a href="http://www.w3.org/Style/CSS/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;CSS&lt;/span&gt;&lt;/a&gt; file allows us to separate styling information from our HTML (or &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;ASPX&lt;/span&gt; if you're into ASP.Net like me), and we all know you can &lt;a href="http://www.w3schools.com/TAGS/tag_script.asp"&gt;link to Javascript files&lt;/a&gt; in the same way.  If you're anything like I was though, all those Javascript files will contain is common "utility" functions.  You'll still have "&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;onclick&lt;/span&gt;" attributes in your HTML calling Javascript methods.&lt;br /&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;JQuery&lt;/span&gt; allows you to get rid of these &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;onclick&lt;/span&gt; calls.  Here's what I do:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Have a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;JS&lt;/span&gt; file per page in your application&lt;/li&gt;&lt;li&gt;Link to this &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;JS&lt;/span&gt; file in your page as you normally link to script files&lt;/li&gt;&lt;li&gt;Do not include any script in your page what so ever&lt;br /&gt;&lt;/li&gt;&lt;li&gt;In the page's &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;JS&lt;/span&gt; file, make use of the $(document).ready call to wire up your event handlers&lt;/li&gt;&lt;/ul&gt;For example: you have a floating div ("&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;helpDiv&lt;/span&gt;") where you want to toggle the visibility based the click of a link ("&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;lnkToggleHelp&lt;/span&gt;").  I used to add an &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;onlick&lt;/span&gt; attribute to the anchor tag calling a Javascript function that would toggle the visibility.&lt;br /&gt;&lt;br /&gt;In &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;JQuery&lt;/span&gt; you can do this in your page's &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;JS&lt;/span&gt; file:&lt;br /&gt;&lt;pre&gt;$("#&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;lnkToggleHelp&lt;/span&gt;").click(function(event){&lt;br /&gt;event.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;preventDefault&lt;/span&gt;();&lt;br /&gt;$("#&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;helpDiv&lt;/span&gt;").toggle();&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;Which separates the behaviour of the page from the structure: leaving you with 3 separate but linked strands of a page: Style (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;CSS&lt;/span&gt;), Structure (HTML), and Behaviour (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;JS&lt;/span&gt; files incorporating &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;JQuery&lt;/span&gt;).  To me it's a whole lot neater.&lt;br /&gt;&lt;br /&gt;That and all the effects and manipulation that you can do with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;JQuery&lt;/span&gt; means I can't see myself writing Javascript in the future without using &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;JQuery&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-2820565032535838653?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/2820565032535838653/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=2820565032535838653' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/2820565032535838653'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/2820565032535838653'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/11/jquery-how-javascript-should-be.html' title='JQuery - How Javascript should be'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-620078941485244253</id><published>2008-11-16T21:12:00.003Z</published><updated>2008-11-16T21:37:07.612Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Shuttle'/><title type='text'>Building a PC - easier than I thought</title><content type='html'>Last week I ordered a &lt;a href="http://eu.shuttle.com/en/desktopdefault.aspx/searchcall-12/searchcategory-275/noblendout-1/tabid-72/170_read-14126/"&gt;Shuttle G5&lt;/a&gt; from &lt;a href="http://www.icubes.co.uk/"&gt;icubes.co.uk&lt;/a&gt; along with a processor, memory, HDDs, and a DVDRW drive.  I've never assembled a PC of my own before, but I've installed enough cards and memory to know enough about what makes one work--so I reckoned I knew enough to take the plunge and go for it.&lt;br /&gt;&lt;br /&gt;And I must say it was relatively easy.  There were a few stumbling blocks, like I'd ordered 2 SATA HDDs and a SATA DVDRW drive and the case only came with 1 SATA cable, but I salvaged cables from my old PC so I didn't have to take a trip to &lt;a href="http://www.maplin.co.uk/?&amp;amp;C=GKW&amp;amp;U=Maplin_Brand&amp;amp;T=%20maplin%20-%20E&amp;amp;gclid=CLuCrYfQ-pYCFQaT1Qod6XQCXw"&gt;Maplins&lt;/a&gt; yesterday afternoon.  Only other problem was smearing the thermal paste onto the processor.  I've fitted procs once before but that came with a template that you stuck onto the bottom of the heatsink and filled.  There wasn't anyhting like that so I just used a piece of an old business card that seemed flexible enough.&lt;br /&gt;&lt;br /&gt;Must be working though because it hasn't over heated yet and its been on all day.  Very quiet too, although my last PC sounded like a jet engine because of all the fans in it.  I like the compactness of it too--it's smaller than the subwoofer that I had with my old PC.&lt;br /&gt;&lt;br /&gt;I was going to post a step by step guide to how I assembled it, but there doesn't really seem to be much point.  The case comes with instructions on what to plug in when, and if you've got all the cables you need you're fine. &lt;br /&gt;&lt;br /&gt;Only things I would say if you've looking to do the same is:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Make sure all the parts will fit into the chassis you're ordering&lt;/li&gt;&lt;li&gt;Don't use too much thermal paste as it can go everywhere if you put too much on&lt;/li&gt;&lt;li&gt;Buy extra SATA cables if you've chosen more than 1 SATA drive&lt;/li&gt;&lt;li&gt;If you're not using IDE drives, you can take out the IDE cable to make room&lt;/li&gt;&lt;li&gt;Your processor may come with a heatsink and fan, but the Shuttle includes one, so use it because it's quieter&lt;/li&gt;&lt;li&gt;If you go with the G5 make sure you mount the DVD drive close enough to the front so the button opens the tray (you'll understand when you get there ;))&lt;/li&gt;&lt;/ul&gt;But apart from that, it's not too difficult.  I wouldn't recommend it to an absolute novice as there's some things that aren't covered in the instructions, but if you know how PCs work you should be fine.  And you'll end up with a pretty PC at the end of it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-620078941485244253?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/620078941485244253/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=620078941485244253' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/620078941485244253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/620078941485244253'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/11/building-pc-easier-than-i-thought.html' title='Building a PC - easier than I thought'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-4273799151500198356</id><published>2008-07-02T18:21:00.002+01:00</published><updated>2008-07-02T18:32:18.173+01:00</updated><title type='text'>An Open Letter to M1 J26-J28 Drivers</title><content type='html'>Work is currently under way to widen the motorway between these two junctions, both north and southbound.  As part of this work a 50mph speed restriction is in place due to narrow lanes that allow the work to take place.&lt;br /&gt;&lt;br /&gt;Could I please remind everyone (or inform, if you haven't realised already) that the outside lane is much narrower than the other 2 and to keep your vehicle in that lane if you choose to drive in it?&lt;br /&gt;&lt;br /&gt;I have lost count of the number of vehicles (well, cars mostly as van drivers seem to be aware of the road they are taking up) that have nearly hit me from drifting towards the middle lane.  That stretch of road is congested enough during rush hour: for God's sake don't add to it by causing a pile up.&lt;br /&gt;&lt;br /&gt;So please folks, stop fiddling with your sat nav.  Stop farting about with your car's onboard computer.  Put the phone down and stop nattering into your hands free kit.  Stop trying to read a god damned book while doing 50mph in a narrow busy lane (yes, I have seen someone doing this).  Stop doing anything that takes your attention away from staying in the lane.  It's not difficult.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-4273799151500198356?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/4273799151500198356/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=4273799151500198356' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/4273799151500198356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/4273799151500198356'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/07/open-letter-to-m1-j26-j28-drivers.html' title='An Open Letter to M1 J26-J28 Drivers'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-4434529119214181209</id><published>2008-06-21T00:52:00.003+01:00</published><updated>2008-06-21T01:24:31.570+01:00</updated><title type='text'>Untitled</title><content type='html'>Friday night/Saturday morning, and I'm killing time until I'm tired enough to sleep. The cat on my lap has his white paw resting in an empty shot glass that did have a neat JD in about half an hour ago. Got the house to myself but there's nothing on TV worth watching so I'm doing what my girlfriend hates me doing. Flicking through the music channels until I find a song I like, then flicking around again when it finishes. &lt;br /&gt;&lt;br /&gt;Whatever happened to Sade?  Can't say I ever liked that kind of music but it'll always scream mid 90s to me. My sister seemed to loop that CD when I was in secondary school and it looks like it just stuck.&lt;br /&gt;&lt;br /&gt;Same with The Bangles. I remember a girl in primary school singing Eternal Flame (think her name was Carla) and the teacher (Mrs Bettison?) saying she wanted to be sent tickets to her concert when she was famous. That was probably 20 years ago now but that song triggered that memory off as well any smell could. &lt;br /&gt;&lt;br /&gt;No Doubt's Don't Speak is on now, and I'm instantly at school again doing my GCSEs wondering what my life will hold and why Hayley chose to wear a black bra under a white top for the last exam of the year. But as soon as it hits it's gone again, and I'm dragged back to now with a cat padding my leg and me wondering where any of this is even going. &lt;br /&gt;&lt;br /&gt;I don't really think it's going anywhere actually. Probably shouldn't be writing blogs at gone midnight after half a bottle of wine and JD but there you go. &lt;br /&gt;&lt;br /&gt;Oh, Black Hawk Down's on&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-4434529119214181209?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/4434529119214181209/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=4434529119214181209' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/4434529119214181209'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/4434529119214181209'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/06/friday-nightsaturday-morning-and-im.html' title='Untitled'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-2883084311798359104</id><published>2008-06-20T09:27:00.003+01:00</published><updated>2008-06-20T10:12:16.974+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web Services'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Creating Mock Web Services in .Net</title><content type='html'>So, a situation arises where your code needs to make a Web Services call out to a different system.  Chances are you'll go through the usual stages of &lt;a href="http://msdn.microsoft.com/en-us/library/d9w023sx.aspx"&gt;adding a Web Reference to your project in Visual Studio&lt;/a&gt;, and then use the generated code to make your call.  Simple, right?&lt;br /&gt;&lt;br /&gt;Well, yes, and Visual Studio goes out of its way to simplify the creation of this client code, so you can get on with calling the service rather than concern yourself with the plumbing that's required.&lt;br /&gt;&lt;br /&gt;But what if the service you are calling &lt;span style="font-weight: bold;"&gt;charges you for every call you make&lt;/span&gt;?  What if you can't guarantee that you will be &lt;span style="font-weight: bold;"&gt;online during the development&lt;/span&gt; of your code?  What if that &lt;span style="font-weight: bold;"&gt;service is currently under development&lt;/span&gt; and you don't know whether it will be available when you are doing your testing?&lt;br /&gt;&lt;br /&gt;If any of these apply you need to &lt;span style="font-weight: bold;"&gt;remove the external call to the web service&lt;/span&gt; from your code.  In a unit test scenario you would probably use something like &lt;a href="http://www.nmock.org/"&gt;NMock&lt;/a&gt; and architect your code to use a &lt;a href="http://en.wikipedia.org/wiki/Dependency_injection"&gt;dependency injection pattern&lt;/a&gt;: injecting an NMock created object that matched an expected interface.&lt;br /&gt;&lt;br /&gt;In other cases what you can do is &lt;span style="font-weight: bold;"&gt;create a mock Web Service&lt;/span&gt;.  One that matches the interface of the live one, but which you control.&lt;br /&gt;&lt;br /&gt;You can easily create interfaces that match a WSDL file by using the &lt;a href="http://msdn.microsoft.com/en-us/library/7h3ystb6.aspx"&gt;WSDL.exe&lt;/a&gt; program.  I have a sneaky suspicion that this tool is used to create the client code from Visual Studio when you add a new Web Reference, but it can also perform the other way around.&lt;br /&gt;&lt;br /&gt;First, &lt;span style="font-weight: bold;"&gt;obtain the &lt;/span&gt;&lt;a style="font-weight: bold;" href="http://en.wikipedia.org/wiki/Web_Services_Description_Language"&gt;WSDL&lt;/a&gt;&lt;span style="font-weight: bold;"&gt; of the Web Servic&lt;/span&gt;e you want to mock up.  (If you are calling a .Net Web Service, then the path will probably end &lt;span style="font-style: italic;"&gt;.asmx&lt;/span&gt;.  To get the WSDL, just append &lt;span style="font-style: italic;"&gt;?wsdl&lt;/span&gt; to the path and you'll get the WSDL XML).  &lt;span style="font-weight: bold;"&gt;Save this to your local machine&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Open up the Visual Studio Command Prompt and type &lt;/span&gt;&lt;a style="font-weight: bold;" href="http://msdn.microsoft.com/en-us/library/7h3ystb6.aspx"&gt;wsdl.exe&lt;/a&gt;.  You should get a heap of text explaining the command line switches, but if you don't your paths aren't mapped correctly.  The wsdl.exe file should be somewhere on your machine though :)&lt;br /&gt;&lt;br /&gt;Once you've found the tool, type&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;wsdl /language:CS /namespace:Your.Namespace.Here /out:Directory\To\Save\To\ /protocol:SOAP /serverinterface finally-your-wsdl-file-here.wsdl&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There are other options too if you need them, like setting proxy username and passwords, but the one shown is what I've used and it works fine.&lt;br /&gt;&lt;br /&gt;This will create a &lt;span style="font-style: italic;"&gt;.cs&lt;/span&gt; file in the &lt;span style="font-style: italic;"&gt;/out&lt;/span&gt; directory that contains a &lt;span style="font-weight: bold;"&gt;number of classes that match the object definitions in the WSDL&lt;/span&gt;.  It will also contain &lt;span style="font-weight: bold;"&gt;one interface that you must implement&lt;/span&gt; in order to complete your mock Web Service.&lt;br /&gt;&lt;br /&gt;To do this, &lt;span style="font-weight: bold;"&gt;create a new ASP.Net Web Application&lt;/span&gt;.  (I guess you could create a Web Site, but I've not tried that as I don't like them).  &lt;span style="font-weight: bold;"&gt;Add the code file&lt;/span&gt; you generated above to the project, then &lt;span style="font-weight: bold;"&gt;add a new Web Service&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;In the code behind for this Web Service, change the class definition so that it &lt;span style="font-weight: bold;"&gt;implements the interface in the generated code&lt;/span&gt;.  Visual Studio should help you out by generating method stubs so the class matches the interface.&lt;br /&gt;&lt;br /&gt;And there you have it, &lt;span style="font-weight: bold;"&gt;place code in the method stubs&lt;/span&gt; to do what you want.&lt;br /&gt;&lt;br /&gt;You now have your mock web service.  &lt;span style="font-weight: bold;"&gt;Run the application&lt;/span&gt; to make sure that it works, and then make a &lt;span style="font-weight: bold;"&gt;note of the address&lt;/span&gt; of the new mock service.  &lt;span style="font-weight: bold;"&gt;Enter this as the URL&lt;/span&gt; of the web service you want to call in your App/Web.config file &lt;span style="font-weight: bold;"&gt;in place of the live one&lt;/span&gt;, and your application should now call your mock instead of the live one.&lt;br /&gt;&lt;br /&gt;A little tip though.  I've noticed that (at least Visual Studio 2008) &lt;span style="font-weight: bold;"&gt;doesn't like attaching to 2 IIS processes for debugging&lt;/span&gt;.  If you are calling your mock service from an ASP.Net application &lt;a href="http://msdn.microsoft.com/en-us/library/a404w14b.aspx"&gt;and you want to debug both&lt;/a&gt;, you'll need to start one of the applications up in the Visual Studio Development Server, instead of running under IIS.  If you do this, &lt;a href="http://msdn.microsoft.com/en-us/library/ms178109.aspx"&gt;make sure you assign an explicit port value&lt;/a&gt; rather than an auto generated one, otherwise your calling code won't be able to call it :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-2883084311798359104?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/2883084311798359104/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=2883084311798359104' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/2883084311798359104'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/2883084311798359104'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/06/creating-mock-web-services-in-net.html' title='Creating Mock Web Services in .Net'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-5108279048984555566</id><published>2008-05-26T21:37:00.005+01:00</published><updated>2008-05-26T22:25:54.194+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Refactoring'/><category scheme='http://www.blogger.com/atom/ns#' term='VB.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Refactoring</title><content type='html'>I've currently got a post on ice about using &lt;a href="http://msdn.microsoft.com/en-us/library/ms345136.aspx"&gt;CLR functions in SQL Server 2005&lt;/a&gt; using LINQ (don't worry Paul, I've not forgotten), but while I mull that over I'll just make a short point about &lt;a href="http://en.wikipedia.org/wiki/Refactoring"&gt;refactoring code&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Regular readers (and Google Analytics tells me that I do have some, at least), might have picked up on a few complaints I've had about VB.Net.  Personally I wish I'd never have to use it, but sometimes rewriting an entire app in C# isn't cost effective so... needs must, and all that.&lt;br /&gt;&lt;br /&gt;Well, I was recently in the midst of a ton of VB.Net code, thinking "I could do with some IDE refactoring support here," after needing to extract a code block into its own method.  Except I can't find any such support in Visual Studio 2008 for such an option.&lt;br /&gt;&lt;br /&gt;Using C# in Visual Studio (2005 and 2008), we have a neat little context menu option called Refactoring, and while it doesn't offer the depth of features that something like &lt;a href="http://www.jetbrains.com/resharper/"&gt;Resharper&lt;/a&gt; offers, it at least allows you to &lt;a href="http://www.refactoring.com/catalog/extractMethod.html"&gt;Extract Method&lt;/a&gt;, which was the refactoring technique I needed to use.&lt;br /&gt;&lt;br /&gt;Long story short, I found &lt;a href="http://www.panopticoncentral.net/archive/2003/11/04/235.aspx"&gt;this post&lt;/a&gt; from the &lt;a href="http://www.panopticoncentral.net/"&gt;VB.Net Technical Lead&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;I’d never even &lt;em&gt;heard&lt;/em&gt; of refactoring until C# added the feature to their IDE. I’ve never bought a copy of, much less read, &lt;a href="http://martinfowler.com/books.html#refactoring"&gt;Refactoring: Improving the Design of Existing Code&lt;/a&gt;.&lt;/blockquote&gt;&lt;br /&gt;I let out an audible sigh after reading that.  In a way it explains a great deal about VB.Net.&lt;br /&gt;&lt;br /&gt;Refactoring should be something that every professional developer knows about and practices every day of their working lives.  It is an integral part of the development cycle, and one which even graduates should at least be aware of.&lt;br /&gt;&lt;br /&gt;If we do not refactor we end up repeating code needlessly.  Although this might produce a working application that passes all current tests, put yourself 6 months, or 6 years down the line where you have to add a new database table, or a column to a table, or a new page to your web application.&lt;br /&gt;&lt;br /&gt;If you've essentially been copy and pasting code, how many places in the code base do you have to change to add that small piece of new functionality?  Answer: unknown, especially if you weren't involved in the initial project.  How do you know that you've caught all the places without executing every branch of the application?&lt;br /&gt;&lt;br /&gt;Answer: you don't, not until you get irate customers yelling at you, and your managers asking why such a small change resulted in the entire app breaking.&lt;br /&gt;&lt;br /&gt;And it's such a simple thing that I have difficultly believing that any developer worth their salt wouldn't see the benefits that it gives.  So if you don't know, then &lt;a href="http://www.refactoring.com/index.html"&gt;read up and get using it&lt;/a&gt;.  Your code can only get better.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-5108279048984555566?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/5108279048984555566/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=5108279048984555566' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/5108279048984555566'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/5108279048984555566'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/05/refactoring.html' title='Refactoring'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-4982093434429115555</id><published>2008-05-07T20:16:00.003+01:00</published><updated>2008-05-07T20:23:35.256+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Extension Methods'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>IEnumerable to DataSet Extension Method</title><content type='html'>&lt;p&gt;I recently had a need to create a DataSet from a List&amp;lt;T&amp;gt;, and found &lt;a href="http://keithelder.net/blog/archive/2006/03/10/Converting-Generic-Lists-or-Collections-to-a-DataSet.aspx" target="_blank"&gt;this post&lt;/a&gt; that did just that.  I was happily using that in C# code, but then had a requirement to use it from a VB.Net app.&lt;/p&gt;  &lt;p&gt;I'm not even going to attempt to hide my contempt for VB, and one of the things that I quickly tire of is typing the exact same thing multiple times.  The Intellisense in VB also doesn't seem as smart as it is in C#, mainly it doesn't help as much when instantiating objects.&lt;/p&gt;  &lt;p&gt;So I wanted a simpler way of calling the code that I had from the post above, and I immediately thought of extension methods.  If I could create an extension method that made a DataSet from an IEnumerable then I could call that from the VB app with a minimal of fuss.&lt;/p&gt;  &lt;p&gt;Kudos must go to &lt;a href="http://keithelder.net/blog/" target="_blank"&gt;Keith Elder&lt;/a&gt; for his &lt;a href="http://keithelder.net/blog/archive/2006/03/10/Converting-Generic-Lists-or-Collections-to-a-DataSet.aspx" target="_blank"&gt;original code&lt;/a&gt;, but if you want it in extension method form, then here it is:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CollectionExtensions&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; DataSet ToDataSet&amp;lt;T&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt;&lt;br /&gt;IEnumerable&amp;lt;T&amp;gt; collection, &lt;span class="kwrd"&gt;string&lt;/span&gt; dataTableName)&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (collection == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt; &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span class="str"&gt;"collection"&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(dataTableName))&lt;br /&gt;{&lt;br /&gt; &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span class="str"&gt;"dataTableName"&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;DataSet data = &lt;span class="kwrd"&gt;new&lt;/span&gt; DataSet(&lt;span class="str"&gt;"NewDataSet"&lt;/span&gt;);&lt;br /&gt;data.Tables.Add(FillDataTable(dataTableName, collection));&lt;br /&gt;&lt;span class="kwrd"&gt;return&lt;/span&gt; data;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; DataTable FillDataTable&amp;lt;T&amp;gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt; tableName,&lt;br /&gt;IEnumerable&amp;lt;T&amp;gt; collection)&lt;br /&gt;{&lt;br /&gt;PropertyInfo[] properties = &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(T).GetProperties();&lt;br /&gt;&lt;br /&gt;DataTable dt = CreateDataTable&amp;lt;T&amp;gt;(tableName,&lt;br /&gt;collection, properties);&lt;br /&gt;&lt;br /&gt;IEnumerator&amp;lt;T&amp;gt; enumerator = collection.GetEnumerator();&lt;br /&gt;&lt;span class="kwrd"&gt;while&lt;/span&gt; (enumerator.MoveNext())&lt;br /&gt;{&lt;br /&gt; dt.Rows.Add(FillDataRow&amp;lt;T&amp;gt;(dt.NewRow(),&lt;br /&gt;enumerator.Current, properties));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;return&lt;/span&gt; dt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; DataRow FillDataRow&amp;lt;T&amp;gt;(DataRow dataRow,&lt;br /&gt;T item, PropertyInfo[] properties)&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;foreach&lt;/span&gt; (PropertyInfo property &lt;span class="kwrd"&gt;in&lt;/span&gt; properties)&lt;br /&gt;{&lt;br /&gt; dataRow[property.Name.ToString()] = property.GetValue(item, &lt;span class="kwrd"&gt;null&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;return&lt;/span&gt; dataRow;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; DataTable CreateDataTable&amp;lt;T&amp;gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt; tableName,&lt;br /&gt;IEnumerable&amp;lt;T&amp;gt; collection, PropertyInfo[] properties)&lt;br /&gt;{&lt;br /&gt;DataTable dt = &lt;span class="kwrd"&gt;new&lt;/span&gt; DataTable(tableName);&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;foreach&lt;/span&gt; (PropertyInfo property &lt;span class="kwrd"&gt;in&lt;/span&gt; properties)&lt;br /&gt;{&lt;br /&gt; dt.Columns.Add(property.Name.ToString());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;return&lt;/span&gt; dt;&lt;br /&gt;}  &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; &lt;/style&gt;It creates a DataSet with one table that has the name you pass in.  In my case I didn't need to name the DataSet explicitly so just used a constant, but the code above could easily be updated to pass in a DataSet name if you need it.&lt;br /&gt;&lt;br /&gt;Now you should be able to call ToDataSet on any object that implements the IEnumerable interface.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-4982093434429115555?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/4982093434429115555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=4982093434429115555' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/4982093434429115555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/4982093434429115555'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/05/ienumerable-to-dataset-extension-method.html' title='IEnumerable to DataSet Extension Method'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-6006166858724881196</id><published>2008-04-22T08:49:00.003+01:00</published><updated>2008-05-07T20:18:57.783+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Extension Methods'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>C# Extension Methods Part 2: Extending Log4Net</title><content type='html'>&lt;p&gt;OK, so after &lt;a href="http://iandykes.blogspot.com/2008/04/c-extension-methods-part-1-introduction.html" target="_blank"&gt;last time's brief introduction&lt;/a&gt; I'll share with you a &lt;a href="http://logging.apache.org/log4net/index.html" target="_blank"&gt;Log4Net&lt;/a&gt; extension that I've made.  It's nothing really too complicated but I hope it will highlight what I feel are the advantages of this technique.&lt;/p&gt;  &lt;p&gt;So, on to business.  If you're like me you'll like your logging code.  I think logs are wonderful, if only to check that your code is doing what you think it is.  Of course, there's always the chance that you'll have too much logging, but that's what log levels are for, right? ;)&lt;/p&gt;  &lt;p&gt;The following is a common pattern I use for logging at pretty much every level (I've shown Debug here):&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;int&lt;/span&gt; someValue = 3;&lt;br /&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (log.IsDebugEnabled)&lt;br /&gt;{&lt;br /&gt; log.DebugFormat(&lt;span class="str"&gt;"This is a value: {0}"&lt;/span&gt;, someValue);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; &lt;/style&gt;Here I have a value I want to log, so I check that we should log and then log out the value.  In this case I guess the check is superfluous, as the statement won't be output if we're not logging at debug anyway, but I like to get into the habit of checking so that when I need to log something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (log.IsDebugEnabled)&lt;br /&gt;{&lt;br /&gt; StringBuilder builder = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringBuilder();&lt;br /&gt; &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 100; i++)&lt;br /&gt; {&lt;br /&gt;     builder.Append(GetSomeLogStatement(i));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; log.Debug(builder.ToString());&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;I only go into the long running loop if I'm going to get some logging output from it.&lt;br /&gt;&lt;br /&gt;When debugging code I like to have log statements that show where the execution path is going.  The easiest way of doing that is to output a log statement when you enter a public method, but if you're doing this a lot then that's a lot of code being reproduced.&lt;br /&gt;&lt;br /&gt;That's when I thought about making an extension method to handle all this for me.  Here's the code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; LogMethodParameters(&lt;span class="kwrd"&gt;this&lt;/span&gt; ILog logger, Level level,&lt;br /&gt;&lt;span class="kwrd"&gt;string&lt;/span&gt; methodName, &lt;span class="kwrd"&gt;params&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt;[] parameters)&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (logger == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span class="str"&gt;"logger"&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (level == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span class="str"&gt;"level"&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (methodName == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span class="str"&gt;"methodName"&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (logger.Logger.IsEnabledFor(level))&lt;br /&gt;{&lt;br /&gt;StringBuilder builder = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringBuilder();&lt;br /&gt;builder.AppendFormat(&lt;span class="str"&gt;"Method: [{0}]. "&lt;/span&gt;, methodName);&lt;br /&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (parameters != &lt;span class="kwrd"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; parameters.Length &amp;gt; 0)&lt;br /&gt;{&lt;br /&gt; &lt;span class="rem"&gt;// parameters.Length is at least 1&lt;/span&gt;&lt;br /&gt; builder.AppendFormat(&lt;span class="str"&gt;"Parameters: (p0: [{0}]"&lt;/span&gt;, GetParameterDisplayValue(parameters[0]));&lt;br /&gt; &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 1; i &amp;lt; parameters.Length; i++)&lt;br /&gt; {&lt;br /&gt;  builder.AppendFormat(&lt;span class="str"&gt;", p{0}: [{1}]"&lt;/span&gt;, i, GetParameterDisplayValue(parameters[i]));&lt;br /&gt; }&lt;br /&gt; builder.Append(&lt;span class="str"&gt;")"&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;logger.Logger.Log(&lt;span class="kwrd"&gt;null&lt;/span&gt;, level, builder.ToString(), &lt;span class="kwrd"&gt;null&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;span class="kwrd"&gt;catch&lt;/span&gt; (Exception ex)&lt;br /&gt;{&lt;br /&gt;log4net.Util.LogLog.Error(&lt;span class="str"&gt;"Exception while logging exception"&lt;/span&gt;, ex);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; GetParameterDisplayValue(&lt;span class="kwrd"&gt;object&lt;/span&gt; param)&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;return&lt;/span&gt; param != &lt;span class="kwrd"&gt;null&lt;/span&gt; ? param : &lt;span class="str"&gt;"(null)"&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DebugMethodParameters(&lt;span class="kwrd"&gt;this&lt;/span&gt; ILog logger,&lt;br /&gt;&lt;span class="kwrd"&gt;string&lt;/span&gt; methodName, &lt;span class="kwrd"&gt;params&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt;[] parameters)&lt;br /&gt;{&lt;br /&gt;LogMethodParameters(logger, Level.Debug, methodName, parameters);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;Like I say, it's nothing too complicated, but it allows you to include this line at the top of each of your public methods:&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;log.DebugMethodParameters(&lt;span class="str"&gt;"Method"&lt;/span&gt;, 1, 2, 3);&lt;/pre&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;And you don't need to worry about anything else, your log file will show that you entered the method with those parameters.&lt;br /&gt;&lt;br /&gt;What I wanted to do was use reflection to figure out what the current method was and what the parameter values are, but this was just a little side task I had to do while in the middle of something else.&lt;br /&gt;&lt;br /&gt;Here are some additions I could make to this method:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Use reflection to get the method name and parameter names&lt;/li&gt;&lt;li&gt;Incorporate the &lt;a href="http://code.msdn.microsoft.com/csharpsamples" target="_blank"&gt;Visual Studio 2008 ObjectDumper sample&lt;/a&gt; to drill down into complex objects to provide a fuller picture of non-primitive types&lt;/li&gt;&lt;li&gt;Allow custom formatting of the log output&lt;/li&gt;&lt;/ul&gt;This is just the start really.  Check out &lt;a href="http://www.extensionmethod.net/" target="_blank"&gt;extensionmethod.net&lt;/a&gt; for  some more samples of what else you can do. (Hmm, that site seems to be having a  few problems at the moment, but check back later and browse what they have).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-6006166858724881196?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/6006166858724881196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=6006166858724881196' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/6006166858724881196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/6006166858724881196'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/04/c-extension-methods-part-2-extending.html' title='C# Extension Methods Part 2: Extending Log4Net'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-5333168723534635433</id><published>2008-04-19T11:37:00.005+01:00</published><updated>2008-05-07T20:19:28.413+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Extension Methods'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>C# Extension Methods Part 1: Introduction</title><content type='html'>&lt;p&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/bb383977.aspx" target="_blank"&gt;Extension methods&lt;/a&gt; are a new feature of C# 3.0 with .Net 3.5.  They allow you to extend existing classes with new methods without having to create a whole new class that inherits from the class you want to add the method to.  First off, why would you want to do this? &lt;/p&gt;  &lt;p&gt;Well, as an example &lt;a href="http://msdn2.microsoft.com/en-us/netframework/aa904594.aspx" target="_blank"&gt;LINQ&lt;/a&gt; makes heavy use of extension methods to provide the functionality to create new expressions easily.  A LINQ extension method might extend &lt;a href="http://msdn2.microsoft.com/en-us/library/system.linq.iqueryable.aspx" target="_blank"&gt;IQueryable&lt;/a&gt; to apply a custom where clause, for example.  In fact, as part of the &lt;a href="http://code.msdn.microsoft.com/csharpsamples" target="_blank"&gt;Visual Studio 2008 samples&lt;/a&gt; you'll find a set of extension methods that does just that.&lt;/p&gt;  &lt;p&gt;So what does an extension method look like?  Here's a very simple example:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Reverse(&lt;span class="kwrd"&gt;this&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; str)&lt;br /&gt;{&lt;br /&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (str == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt; {&lt;br /&gt;     &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span class="str"&gt;"str"&lt;/span&gt;);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; StringBuilder builder = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringBuilder();&lt;br /&gt; &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; i = str.Length - 1; i &amp;gt;= 0; i--)&lt;br /&gt; {&lt;br /&gt;     builder.Append(str[i]);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; builder.ToString();&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;style type="text/css"&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060;&lt;/style&gt;Here we have a static class StringExtensionMethods that contains a Reverse method, which reverses the order of the characters in a string.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Notice that the parameter being passed into the Reverse method has the "this" keyword preceding it.  This tells the compiler that this is an extension method for the string class.&lt;/p&gt;&lt;br /&gt;You can now use this method on &lt;strong&gt;any string object in any class that uses the namespace that this static class is in&lt;/strong&gt;.  We also get full Intellisense support in Visual Studio 2008:&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://lh4.ggpht.com/ian.dykes/SAnLYfF1jJI/AAAAAAAAAEE/JzTaYuDRaT8/reverseCodeGrab%5B6%5D.jpg"&gt;&lt;img style="border: 0px none ;" alt="reverseCodeGrab" src="http://lh3.ggpht.com/ian.dykes/SAnLZPF1jKI/AAAAAAAAAEM/Zm43iwQTKpY/reverseCodeGrab_thumb%5B3%5D.jpg" border="0" height="125" width="304" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;br /&gt;There are a few things to be aware of though.  Consider this piece of code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;string&lt;/span&gt; thisIsNull = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;br /&gt;Console.Write(thisIsNull.Reverse()); &lt;/pre&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;style type="text/css"&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;If Reverse was a standard method on the string object, then we would get a NullReferenceException being thrown when we try to call the method.&lt;br /&gt;&lt;br /&gt;However, &lt;strong&gt;an extension method on a null object will still be called&lt;/strong&gt;.  It is the responsibility of the extension method to check for null values.&lt;br /&gt;&lt;br /&gt;The extension method is pretty much just syntactic sugar around a standard static "helper" style method.  So when the method is called it doesn't actually need to be part of an instance.&lt;br /&gt;&lt;br /&gt;For this reason, make sure you should still check that the parameter is not null before using it, as you would in a normal method.&lt;br /&gt;As a quick aside, this is a perfectly functional extension method:&lt;style type="text/css"&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; IsNull(&lt;span class="kwrd"&gt;this&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; obj)&lt;br /&gt;{&lt;br /&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; obj == &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;It could then be called like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;string&lt;/span&gt; thisIsNull = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (thisIsNull.IsNull())&lt;br /&gt;{&lt;br /&gt; Console.Write(&lt;span class="str"&gt;"Was null"&lt;/span&gt;);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;So we can create extension methods that easily provide some additional functionality to a class.  Next time, I'll show how I've implemented a simple extension method to &lt;a href="http://logging.apache.org/log4net/index.html" target="_blank"&gt;Log4Net&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-5333168723534635433?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/5333168723534635433/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=5333168723534635433' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/5333168723534635433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/5333168723534635433'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/04/c-extension-methods-part-1-introduction.html' title='C# Extension Methods Part 1: Introduction'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/ian.dykes/SAnLZPF1jKI/AAAAAAAAAEM/Zm43iwQTKpY/s72-c/reverseCodeGrab_thumb%5B3%5D.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-8138468136363097500</id><published>2008-04-02T20:54:00.005+01:00</published><updated>2008-04-02T22:13:24.584+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Beginning Lambda Expressions in C#</title><content type='html'>&lt;div style="margin: 0px; padding: 5px; float: right;"&gt;&lt;br /&gt;&lt;script type="text/javascript"&gt;digg_url ='http://iandykes.blogspot.com/2008/04/beginning-lambda-expressions-in-c.html';&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;script src="http://digg.com/tools/diggthis.js" type="text/javascript"&gt;&lt;/script&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I think I've been using &lt;a href="http://msdn2.microsoft.com/en-us/library/bb425822.aspx"&gt;LINQ to SQL&lt;/a&gt; for about a week now, and one of the (many) things to conquer on that particular learning curve are &lt;a href="http://msdn2.microsoft.com/en-us/library/bb397687.aspx"&gt;lambda expressions&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Lambda expressions are a new feature of &lt;a href="http://msdn2.microsoft.com/en-us/vcsharp/aa336745.aspx"&gt;C# 3.0&lt;/a&gt; using &lt;a href="http://www.simple-talk.com/dotnet/.net-framework/.net-3.5-language-enhancements/"&gt;.Net 3.5&lt;/a&gt;, and look something like this:&lt;br /&gt;&lt;pre&gt;t =&amp;gt; t.Contains("hello")&lt;/pre&gt;When starting out this expression can look very strange, but once you get your head around it they are pretty simple... well, in most cases.&lt;br /&gt;&lt;br /&gt;Lambda expressions are like &lt;a href="http://weblogs.asp.net/dwahlin/archive/2007/04/23/The-Power-of-Anonymous-Methods-in-C_2300_.aspx"&gt;anonymous delegates&lt;/a&gt;, they have input parameters, and an output result, and the new =&amp;gt; syntax ties them both together.  What the example above means is that there is a parameter "t" (in this case a string), and it returns a bool (the return type of the &lt;a href="http://msdn2.microsoft.com/en-us/library/dy85x1sa.aspx"&gt;string.Contains&lt;/a&gt; method).&lt;br /&gt;&lt;br /&gt;But how do we know what these types are?  They can be inferred from the type declaration.  The above example would be meaningless on it's own, but when put together like this:&lt;pre&gt;// delegate that takes a string and returns a bool&lt;br /&gt;public delegate bool CheckString(string arg);&lt;br /&gt;&lt;br /&gt;// create an instance of the delegate using a lambda expression&lt;br /&gt;CheckString newDelegate = s =&amp;gt; s.Contains("hello");&lt;br /&gt;&lt;br /&gt;// use the delegate to show the expression works&lt;br /&gt;Console.WriteLine("Value: {0}", newDelegate("hello world"));&lt;/pre&gt;We can see that the types are inferred from the fact we are creating a CheckString delegate. The delegate would return true when called with this string.&lt;br /&gt;&lt;br /&gt;So how does this help us with LINQ?  Well, in LINQ queries you'll often see that you need to specify parameters that have types that contain something like this:&lt;pre&gt;Func&amp;lt;T0, TR&amp;gt;&lt;/pre&gt;And what the hell does that mean?  Well, as part of the framework we have the following generic delegates already defined for us:&lt;pre&gt;public delegate TR Func&amp;lt;TR&amp;gt;();&lt;br /&gt;public delegate TR Func&amp;lt;T0, TR&amp;gt;(T0 a0);&lt;br /&gt;public delegate TR Func&amp;lt;T0, T1, TR&amp;gt;(T0 a0, T1 a1);&lt;br /&gt;public delegate TR Func&amp;lt;T0, T1, T2, TR&amp;gt;(T0 a0, T1 a1, T2 a2);&lt;br /&gt;public delegate TR Func&amp;lt;T0, T1, T2, T3, TR&amp;gt;(T0 a0, T1 a1, T2 a2, T3 a3);&lt;/pre&gt;These delegates simply say that given the types specified, the delegate should return a type.  In an abstract way, that's all a delegate is really: so don't worry that it can look a bit crazy.&lt;br /&gt;&lt;br /&gt;Using this I could rewrite the previous example like this:&lt;pre&gt;// create a lambda expression&lt;br /&gt;Func&amp;lt;string, bool&amp;gt; newDelegate = s =&amp;gt; s.Contains("hello");&lt;br /&gt;&lt;br /&gt;// use the delegate to show the expression works&lt;br /&gt;Console.WriteLine("Value: {0}", newDelegate("hello Mr Coupland"));&lt;/pre&gt;I don't have to define a CheckString delegate any more, and can just use the inbuilt generics to specify what the delegate interface is.&lt;br /&gt;&lt;br /&gt;So what does this all mean?  Well, if you need to pass in delegates to a method call, instead of having to define the delegate's interface, then structuring an anonymous delegate to match it, you can just use one of the Func delegates and a lambda expression, like in this really contrived example:&lt;pre&gt;// create a boring method that doesn't do much&lt;br /&gt;public bool StringConditionCheck(string str, Func&amp;lt;string, bool&amp;gt; exp)&lt;br /&gt;{&lt;br /&gt;  return exp(str);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// call the method from somewhere else&lt;br /&gt;public void MyOtherMethod()&lt;br /&gt;{&lt;br /&gt;  Console.WriteLine(StringConditionCheck("sjdl", s =&amp;gt; s.StartsWith("s")));&lt;br /&gt;}&lt;/pre&gt;That example's probably a little too simple, but it shows what you can do with a lambda expression passed in to another method.&lt;br /&gt;&lt;br /&gt;This is nothing new in itself, you can do all of that with anonymous delegates in .Net 2.0 (and with normal delegates before that), but now there's less code to write.&lt;br /&gt;&lt;br /&gt;And when you can create delegates so effortlessly, it makes creating generic Expressions for our LINQ expression trees really simple, but that's for another post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-8138468136363097500?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/8138468136363097500/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=8138468136363097500' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/8138468136363097500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/8138468136363097500'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/04/beginning-lambda-expressions-in-c.html' title='Beginning Lambda Expressions in C#'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-3301300385228145306</id><published>2008-03-31T20:18:00.004+01:00</published><updated>2008-03-31T20:36:22.376+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net 2.0'/><title type='text'>High memory usage and slow load times in .Net 2.0 apps</title><content type='html'>Stumbled across news of &lt;a href="http://support.microsoft.com/kb/945757"&gt;what was fixed in the .Net 2.0 SP1 update&lt;/a&gt; last week.  Things of note:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://support.microsoft.com/kb/929422/"&gt;Memory usage may increase&lt;/a&gt; for .NET Framework Windows applications that call COM+ applications after you upgrade to the .NET Framework 2.0&lt;/li&gt;&lt;li&gt;&lt;a href="http://support.microsoft.com/kb/917495/"&gt;You may receive an OutOfMemoryException exception&lt;/a&gt; when you run a .NET Framework 2.0-based application&lt;/li&gt;&lt;li&gt;Out of memory exceptions may occur when you run an application that is built by using the &lt;a href="http://support.microsoft.com/kb/912884/"&gt;.NET Framework 2.0 in a high-load environment&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://support.microsoft.com/kb/944157/"&gt;You may experience a significant delay when you make the first request&lt;/a&gt; to an ASP.NET Web application that is running on Windows Server 2003&lt;/li&gt;&lt;/ul&gt;And some more interesting ones that may be useful:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Blocking problems may occur when you use SQL Server to store &lt;a href="http://support.microsoft.com/kb/939866/"&gt;ASP.NET session state information for a Web site that experiences high loads&lt;/a&gt;&lt;/li&gt;&lt;li&gt;The operation takes a long time to finish &lt;a href="http://support.microsoft.com/kb/939520/"&gt;when you rename a control by using the Properties window in Visual Studio 2005&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Error message when you call the "System.Xml.Xsl.XslTransform.Transform" method two times in a .NET Framework 2.0-based application: &lt;a href="http://support.microsoft.com/kb/937320/"&gt;"Circular reference in the definition of variable &amp;lt;variable name&amp;gt;"&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Error message when you try to &lt;a href="http://support.microsoft.com/kb/935669/"&gt;marshal a distributed transaction across application domains by using the EnterpriseServices component in the .NET Framework 2.0: "Unhandled Exception: System.Runtime.Serialization.SerializationException"&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://support.microsoft.com/kb/935287/"&gt;A multipart/mixed MIME part is added unnecessarily&lt;/a&gt; when you use the System.Net.Mail namespace to send an e-mail message in the .NET Framework 2.0&lt;/li&gt;&lt;li&gt;&lt;a href="http://support.microsoft.com/kb/926595/"&gt;Server garbage collector threads may enter an endless loop condition&lt;/a&gt; in the .NET Framework 2.0&lt;/li&gt;&lt;/ul&gt;Make sure you &lt;a href="http://support.microsoft.com/kb/945757"&gt;check out the full list of fixes&lt;/a&gt; to see what might affect your systems.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-3301300385228145306?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/3301300385228145306/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=3301300385228145306' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/3301300385228145306'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/3301300385228145306'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/03/high-memory-usage-and-slow-load-times.html' title='High memory usage and slow load times in .Net 2.0 apps'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-1968439497613225205</id><published>2008-03-25T19:17:00.006Z</published><updated>2008-03-26T20:26:21.637Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>More on goto in C#</title><content type='html'>Akidan's posted a comment back on &lt;a href="http://devproj20.blogspot.com/2007/10/do-you-use-goto-in-c.html"&gt;my old "goto" post from October&lt;/a&gt; last year, and it's got me thinking about it again.  The original post was prompted by seeing gotos in .Net Framework code using &lt;a href="http://www.aisto.com/roeder/dotnet/"&gt;Reflector&lt;/a&gt;, but what we were actually seeing was an optimised version of the code.&lt;br /&gt;&lt;br /&gt;The real question comes down to code readability.  A high level language like C# has constructs that make a goto statement superfluous, and a compiler which is able to recognise when a goto can replace some branching code.  So from the perspective of writing high performance code, we don't need to worry: we can let the compiler figure out how best to structure the internal workings for us.&lt;br /&gt;&lt;br /&gt;And here is the crux of the matter.  If we don't need to worry so much about execution speed, then surely we should write code with an eye towards maintainability?&lt;br /&gt;&lt;br /&gt;Now, I'm not saying that gotos make code inherently unmaintainable or unreadable: I'm willing to accept that there could be situations where they can be used, but only then used with caution.&lt;br /&gt;&lt;br /&gt;I still stand by my belief that gotos should be avoided in code that you write yourself.  Using Akidan's two methods as an example: the non-goto one is certainly more readable.  It's clear that the "if" is  comprised of 2 checks that results in the same outcome, and having them together like that makes it difficult to separate them later on by mistake.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-1968439497613225205?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/1968439497613225205/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=1968439497613225205' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/1968439497613225205'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/1968439497613225205'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/03/more-on-goto-in-c.html' title='More on goto in C#'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-7819892058633797608</id><published>2008-03-20T11:22:00.002Z</published><updated>2008-03-20T11:30:06.115Z</updated><title type='text'>The customer isn't always right</title><content type='html'>&lt;a href="http://positivesharing.com/2008/03/top-5-reasons-why-the-customer-is-always-right-is-wrong/"&gt;Top 5 reasons why “The customer is Always Right” is wrong&lt;/a&gt; [&lt;a href="http://duggmirror.com/business_finance/Top_5_reasons_why_The_Customer_is_Always_Right_is_Wrong_3/"&gt;mirror here&lt;/a&gt;]&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Using the slogan “The customer is always right” abusive customers can demand just about anything - they’re right by definition, aren’t they? This makes the employees’ job that much harder, when trying to rein them in.&lt;/p&gt; &lt;p&gt;Also, it means that abusive people get better treatment and conditions than nice people. That always seemed wrong to me, and it makes much more sense to be nice to the nice customers to keep &lt;em&gt;them&lt;/em&gt; coming back.&lt;/p&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-7819892058633797608?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/7819892058633797608/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=7819892058633797608' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/7819892058633797608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/7819892058633797608'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/03/customer-isnt-always-right.html' title='The customer isn&apos;t always right'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-5693570466253119940</id><published>2008-03-18T11:21:00.004Z</published><updated>2008-03-18T12:05:00.283Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='Firefox'/><title type='text'>Enabling Java applets in Firefox on Ubuntu</title><content type='html'>&lt;div style="margin: 0px; padding: 5px; float: right;"&gt;&lt;br /&gt;&lt;script type="text/javascript"&gt;digg_url ='http://iandykes.blogspot.com/2008/03/enabling-java-applets-in-firefox-on.html';&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;script src="http://digg.com/tools/diggthis.js" type="text/javascript"&gt;&lt;/script&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;First problem I've encountered with Ubuntu was trying to use Facebook's photo uploader from Firefox.  It all started out well: I went to the the page and was told I needed to install Java, and Ubuntu presented me with a list.&lt;br /&gt;&lt;br /&gt;Here is where I made my first mistake, I installed the first one on the list, which wasn't Sun's JRE.  I can't remember the name of the one I installed, but after sitting through the installation I got back to Facebook and had a dialog pop up saying the &lt;span style="font-style: italic;"&gt;GNU classpath had not been set&lt;/span&gt;, or something along those lines anyway.&lt;br /&gt;&lt;br /&gt;So I went to &lt;a href="http://www.java.com/en/download/installed.jsp"&gt;verify my Java plugin&lt;/a&gt;, and got a message saying I wasn't running the latest version, and provided links to download the latest.  Not really knowing what an RPM was, I chose the "&lt;a href="http://www.java.com/en/download/linux_manual.jsp?locale=en&amp;amp;host=www.java.com:80"&gt;Linux (self extracting file)&lt;/a&gt;" option, and &lt;a href="http://www.java.com/en/download/help/5000010500.xml#selfextracting"&gt;consulted the instructions&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Second problem came now.  The first instruction was to &lt;a href="http://en.wikipedia.org/wiki/Su_%28Unix%29"&gt;SU to root&lt;/a&gt;, which required a password, and I'm pretty sure I never set a root password when I installed.&lt;br /&gt;&lt;br /&gt;But no problem, I just chose System - Administration - Users and Groups from the top menu in Ubuntu, selected the root user and assigned a password.  I then carried on following Sun's instructions to install Java, which were simple enough.&lt;br /&gt;&lt;br /&gt;Then came the section &lt;a href="http://www.java.com/en/download/help/5000010500.xml#enable"&gt;Enable and Configure&lt;/a&gt;, in which I had to tell Firefox to use this new JRE for applets.&lt;br /&gt;&lt;br /&gt;Neat little tip that I didn't know about in Firefox is that if you type &lt;span style="font-style: italic;"&gt;about:plugins&lt;/span&gt; in the address bar you're given a list of the installed plugins, which I was able to use to remove the old plugin that didn't work.&lt;br /&gt;&lt;br /&gt;The plugins are just &lt;a href="http://en.wikipedia.org/wiki/Symbolic_link"&gt;symbolic links&lt;/a&gt; in the firefox/plugins directory, so enabling one plugin means creating a new link in there, and removing the other effectively uninstalls the old one.&lt;br /&gt;&lt;br /&gt;Job done, Facebook's photo uploader (and I assume other Java applets) now works properly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-5693570466253119940?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/5693570466253119940/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=5693570466253119940' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/5693570466253119940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/5693570466253119940'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/03/enabling-java-applets-in-firefox-on.html' title='Enabling Java applets in Firefox on Ubuntu'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-456259506844928300</id><published>2008-03-18T10:32:00.004Z</published><updated>2008-03-18T10:37:16.864Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='XNA'/><category scheme='http://www.blogger.com/atom/ns#' term='CaveIn'/><title type='text'>XNA 3D Game - CaveIn</title><content type='html'>Stumbled across a game called &lt;a href="http://www.johnnydeath.com/cavein3d/index.php"&gt;CaveIn&lt;/a&gt; over at &lt;a href="http://www.virtualrealm.com.au/blogs/mykre/archive/2008/03/17/xna-game-cavein-3d.aspx"&gt;Mykres Space&lt;/a&gt;.  It's a top down 3rd person game where you have to rescue people from a mine, and solve puzzles along the way.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=ntvjJjnhvqY"&gt;Check out the video&lt;/a&gt; for it.  Looks nice.&lt;br /&gt;&lt;br /&gt;&lt;object height="355" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/ntvjJjnhvqY&amp;amp;hl=en"&gt;&lt;param name="wmode" value="transparent"&gt;&lt;embed src="http://www.youtube.com/v/ntvjJjnhvqY&amp;amp;hl=en" type="application/x-shockwave-flash" wmode="transparent" height="355" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-456259506844928300?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/456259506844928300/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=456259506844928300' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/456259506844928300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/456259506844928300'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/03/xna-game-cavein3d.html' title='XNA 3D Game - CaveIn'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-801000456840306973</id><published>2008-03-17T21:20:00.007Z</published><updated>2008-03-17T21:36:43.108Z</updated><title type='text'>Well I find them funny anyway....</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://imgs.xkcd.com/comics/exploits_of_a_mom.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 420px;" src="http://imgs.xkcd.com/comics/exploits_of_a_mom.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://imgs.xkcd.com/comics/goto.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 420px;" src="http://imgs.xkcd.com/comics/goto.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Click to enlarge.&lt;br /&gt;&lt;br /&gt;Or go &lt;a href="http://www.xkcd.com/327/"&gt;straight&lt;/a&gt; to the &lt;a href="http://www.xkcd.com/292/"&gt;source&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-801000456840306973?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/801000456840306973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=801000456840306973' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/801000456840306973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/801000456840306973'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/03/well-i-find-it-funny-anyway.html' title='Well I find them funny anyway....'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-4570540920152078671</id><published>2008-03-17T10:57:00.002Z</published><updated>2008-03-17T11:01:53.138Z</updated><title type='text'>Need 1 second of surprise? How about a stuffed toy?</title><content type='html'>Not entirely sure I'm convinced this is serious, but I've just seen an episode of &lt;a href="http://dsc.discovery.com/tv/future-weapons/future-weapons.html"&gt;Future Weapons&lt;/a&gt; which featured the Kitty Cornershot.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=W0Q7MLR89p8"&gt;Check out the video&lt;/a&gt; and see for yourself.&lt;br /&gt;&lt;br /&gt;&lt;object height="355" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/W0Q7MLR89p8&amp;amp;hl=en"&gt;&lt;param name="wmode" value="transparent"&gt;&lt;embed src="http://www.youtube.com/v/W0Q7MLR89p8&amp;amp;hl=en" type="application/x-shockwave-flash" wmode="transparent" height="355" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-4570540920152078671?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/4570540920152078671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=4570540920152078671' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/4570540920152078671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/4570540920152078671'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/03/need-1-second-of-surprise-how-about.html' title='Need 1 second of surprise? How about a stuffed toy?'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-706140940226971752</id><published>2008-03-12T19:58:00.003Z</published><updated>2008-03-12T20:45:07.617Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='jPod'/><category scheme='http://www.blogger.com/atom/ns#' term='Coupland'/><title type='text'>Douglas Coupland's jPod</title><content type='html'>I've been a huge fan of &lt;a href="http://www.coupland.com/books/index.html"&gt;Douglas Coupland's books&lt;/a&gt; since reading &lt;a href="http://en.wikipedia.org/wiki/Microserfs"&gt;Microserfs&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Generation_X:_Tales_for_an_Accelerated_Culture"&gt;Generation X&lt;/a&gt; when I was at college, right up to his new one &lt;a href="http://en.wikipedia.org/wiki/The_Gum_Thief"&gt;The Gum Thief&lt;/a&gt; which I'm currently reading at the moment.&lt;br /&gt;&lt;br /&gt;His book before that one was called &lt;a href="http://en.wikipedia.org/wiki/JPod"&gt;jPod&lt;/a&gt;, which was billed as "&lt;a href="http://books.guardian.co.uk/reviews/generalfiction/0,,1779649,00.html"&gt;Microserfs for the Google generation&lt;/a&gt;", which I enjoyed as much as any of his other books.&lt;br /&gt;&lt;br /&gt;I was surprised to stumble across news a few months ago that &lt;a href="http://www.cbc.ca/jpod/"&gt;jPod was being made into a TV series&lt;/a&gt;, and &lt;a href="http://www.youtube.com/watch?v=Av19KlsTM5Y"&gt;checked out the trailer&lt;/a&gt; to see what they'd done.  And I must admit that I wasn't too impressed.  Maybe it was just the usual feeling you have when you find out that someone else's interpretation of a piece isn't the same as your own, but in this case it was something more as well.&lt;br /&gt;&lt;br /&gt;I've always found his work utterly engrossing, and I don't agree with some reviewers who say Coupland isn't a master of characterisation.  For me, as a 20 something member of the IT rat race, I see his characters all around me (and I'm friends with some of them).&lt;br /&gt;&lt;br /&gt;So it was with some disappointment that I finished watching the trailer, and I can't say that I was terribly bothered if it ever made it across the pond.  I'd probably watch it if it did though.&lt;br /&gt;&lt;br /&gt;But now I guess that's less likely to happen, as the news breaks that &lt;a href="http://www.canada.com/globaltv/globalshows/et_story.html?id=8dc1e531-4e7f-4814-b007-c782f3e36b73"&gt;CBC has cancelled the show&lt;/a&gt;, and it will not be returning for a second season.&lt;br /&gt;&lt;br /&gt;But already the &lt;a href="http://blog.polity.ca/2008/03/11/save-jpod/"&gt;fans have staged a protest&lt;/a&gt;, urging people to &lt;a href="http://culturepopped.blogspot.com/2008/03/save-jpod.html"&gt;contact CBC to register their disgust&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Will this work?  I doubt it, but there is precedent though: Futurama and Family Guy were both cancelled by Fox, only to reappear as straight to DVD after a backlash from fans.  So maybe there is hope for the people wishing to see it return.&lt;br /&gt;&lt;br /&gt;Me? I'm still waiting for the &lt;a href="http://www.heroestheseries.com/is-the-end-of-the-writers-strike-near-is-heroes-saved/"&gt;second season for Heroes to restart&lt;/a&gt;...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-706140940226971752?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/706140940226971752/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=706140940226971752' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/706140940226971752'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/706140940226971752'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/03/douglas-couplands-jpod.html' title='Douglas Coupland&apos;s jPod'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-5507002024578210950</id><published>2008-03-11T15:27:00.003Z</published><updated>2008-03-11T15:46:49.006Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenOffice'/><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><title type='text'>Using Ubuntu</title><content type='html'>I must say I do like all the nice animations and flourishes that Ubuntu gives to all the windows.  They seem to float, fade and snap to position a lot smoother than I've seen on Windows.  I particularly like how they seem to stretch and flop into place when you maximise to full screen.&lt;br /&gt;&lt;br /&gt;I've not had many problems either.  Today I've been doing a lot of admin stuff setting myself up to start contracting in a couple of weeks: just the usual sstuff of writing letters, sending emails, copying files to my USB stick, editing images; and I've been fine.&lt;br /&gt;&lt;br /&gt;Makes me think back to reading a comment on &lt;a href="http://digg.com/software/50_Proprietary_Programs_We_All_Hate_and_the_OS_Alternatives"&gt;this Digg article&lt;/a&gt;, which said:&lt;br /&gt;&lt;blockquote&gt; I'll use Open Office when it stops looking and running like Word 97&lt;/blockquote&gt;&lt;br /&gt;But he's being overly harsh.  I've only used the word processor for a couple of letters and was quite pleased with the whole experience.  It lets you write documents, checks spelling as you type, auto corrects typos, format text and the like: what more can you need?&lt;br /&gt;&lt;br /&gt;How many features of Office do you actually use day-to-day?  Do you really need to fork out 200+ quid to have those when you can do most things using free software?&lt;br /&gt;&lt;br /&gt;Only thing I will say though, is that the title bar of windows I have maximised occasionally disappears when I hover over it.  I'm not sure if this is a feature though, to stop you clicking the bar when you mean to click the menu along the top.  But it's a minor annoyance at best, and I've enjoyed the experience so far.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-5507002024578210950?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/5507002024578210950/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=5507002024578210950' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/5507002024578210950'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/5507002024578210950'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/03/using-ubuntu.html' title='Using Ubuntu'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-7058984041915419096</id><published>2008-03-10T20:10:00.002Z</published><updated>2008-03-10T20:50:06.182Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><title type='text'>Installing Ubuntu</title><content type='html'>So I've decided to take the plunge and dual boot my desktop PC with XP and Ubuntu.  I've played around with the LiveCD version for about an hour, so I know what to expect.&lt;br /&gt;&lt;br /&gt;I'm &lt;a href="http://www.psychocats.net/ubuntu/installing"&gt;following these instructions&lt;/a&gt;, but I needn't have bothered as the setup wizard is pretty self explanatory.  The only thing I needed to double (and triple check) was the disk drive I'm installing to.&lt;br /&gt;&lt;br /&gt;I have 2 physical hard drives, one with Windows (C:) and one that I just used for data (D:).  Preparing for installing Ubuntu I copied everything I needed from D: to an external drive.  But knowing that the C: and D: names were Windows specific I checked in the LiveCD environment what names Ubuntu gives the drives.&lt;br /&gt;&lt;br /&gt;The installer's currently at 70% as I write this on my laptop, so I hope that my D: drive really &lt;span style="font-style: italic;"&gt;was&lt;/span&gt; called /media/sdb1, or else I've just buggered my machine...&lt;br /&gt;&lt;br /&gt;It should be fine though... I think....  C: was the master drive, and D: the slave, so it made sense that I would have an sda1 and an sdb1.  I hope anyway.&lt;br /&gt;&lt;br /&gt;82% now, currently &lt;span style="font-style: italic;"&gt;Configuring apt&lt;/span&gt;, whatever that means.&lt;br /&gt;&lt;br /&gt;88%, &lt;span style="font-style: italic;"&gt;Importing documents and settings&lt;/span&gt;... strange, as I told the wizard I didn't want to do that...&lt;br /&gt;&lt;br /&gt;94%, &lt;span style="font-style: italic;"&gt;Configuring hardware&lt;/span&gt;... I guess if it's all going to fall over in a heap then it'll probably do it now...&lt;br /&gt;&lt;br /&gt;Done. Although I'm sure it said it was removing something before that window popped up.  Not sure what. Restart now, I guess now I find out if I've screwed up...&lt;br /&gt;&lt;br /&gt;Well I've got a boot menu at least, 3 different instances of Ubuntu (generic, recovery, and memtest86+) and Windows XP! Cool, I'll boot back to Windows to make sure I've not messed up.  Yay!  Still there, and I can no longer see my D: drive, which is as expected if the partition table has changed.&lt;br /&gt;&lt;br /&gt;Now for the proper test, will it boot to Ubuntu?&lt;br /&gt;&lt;br /&gt;Well it's asking for a username, and the display looks a hell of a lot better than in LiveCD mode.  Very quick to get to this stage too.&lt;br /&gt;&lt;br /&gt;Apparently I need to enable some "restricted drivers", as my graphics card needs a driver from Nvidia, which isn't "free software" as the Ubuntu people can't look at the source code.  That driver's downloading now.  And it installed itself too, that was easy enough.  But I need to restart.  Ok, restart.&lt;br /&gt;&lt;br /&gt;That was very quick there, although I guess all operating systems are when they're first installed.&lt;br /&gt;&lt;br /&gt;Right, so what're these software updates it's telling me about?  Apparently there are 196 updates to apply, a total of 245.4MB.  Might kick that off tomorrow.  Oh, neat little window animation there when I closed it.&lt;br /&gt;&lt;br /&gt;So, right: looks like that's installed then.  Easy enough, if a bit nail biting at times.  Only took about half an hour as well.  Although I'm not sure about that brown swirl of a desktop background, have to get rid of that.  I'll have a play and see how I get on.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-7058984041915419096?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/7058984041915419096/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=7058984041915419096' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/7058984041915419096'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/7058984041915419096'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/03/installing-ubuntu.html' title='Installing Ubuntu'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-7166021682593065376</id><published>2008-03-10T19:18:00.004Z</published><updated>2008-03-10T20:13:28.479Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='YouTube'/><category scheme='http://www.blogger.com/atom/ns#' term='Vista'/><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><title type='text'>Vista vs Linux</title><content type='html'>&lt;a href="http://iandykes.blogspot.com/2008/03/ubuntu-first-impressions.html"&gt;Neil's commented&lt;/a&gt; on seeing a Vista Vs Linux video on YouTube.  Check it out:&lt;br /&gt;&lt;br /&gt;&lt;object height="355" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/xC5uEe5OzNQ"&gt;&lt;param name="wmode" value="transparent"&gt;&lt;embed src="http://www.youtube.com/v/xC5uEe5OzNQ" type="application/x-shockwave-flash" wmode="transparent" height="355" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=xC5uEe5OzNQ"&gt;Direct Link Here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-7166021682593065376?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/7166021682593065376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=7166021682593065376' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/7166021682593065376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/7166021682593065376'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/03/vista-vs-linux.html' title='Vista vs Linux'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-8255155043500892159</id><published>2008-03-10T15:57:00.004Z</published><updated>2008-03-10T20:13:57.157Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='XNA'/><category scheme='http://www.blogger.com/atom/ns#' term='Xbox'/><title type='text'>Back to XNA - Programming Considerations</title><content type='html'>I've got 2 weeks until I start contracting for &lt;a href="http://www.eon-uk.com/"&gt;E.ON&lt;/a&gt; so thought I'd get back to playing with XNA.  Well, actually that's a lie.  I started out this morning on Call of Duty 4, but kept dying on All Ghillied Up so &lt;span style="font-style: italic;"&gt;then&lt;/span&gt; I decided to start playing with XNA.&lt;br /&gt;&lt;br /&gt;I've signed up for the &lt;a href="http://creators.xna.com/"&gt;XNA Creators Club&lt;/a&gt; and tried launching the Space Wars starter kit project on my Xbox.  Took a while to deploy all the content, but then again I am going over a wireless connection.  I was impressed though, and started to think about what kind of game I could try to make.&lt;br /&gt;&lt;br /&gt;Whatever I choose, I thought, I need to understand how the GamePad class works.  So I started with a simple game that just output the state of the pad as a string to the screen.  And it's here where I found my first problem.  The screen on a television is very different to the monitor I was using for the Windows games I've made previously.&lt;br /&gt;&lt;br /&gt;Firstly, the TV's refresh rate is lower than my monitor's so you can see slight flickering when you have a bright screen.  Pretty sure that will give me a headache if I look at it too much, so my Xbox games will need a darker background than on PC.&lt;br /&gt;&lt;br /&gt;But probably more important is that TV screens can trim off part of the display, so you don't get the full screen to play with.  &lt;a href="http://msdn2.microsoft.com/en-us/library/bb203938%28MSDN.9%29.aspx"&gt;Xbox 360 Programming Considerations&lt;/a&gt; explains this, and other things to be aware of when making games.&lt;br /&gt;&lt;br /&gt;So I'll give it some thought, and figure out what type of game I want to make.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-8255155043500892159?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/8255155043500892159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=8255155043500892159' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/8255155043500892159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/8255155043500892159'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/03/back-to-xna-programming-considerations.html' title='Back to XNA - Programming Considerations'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-8606097808285674231</id><published>2008-03-06T21:24:00.003Z</published><updated>2008-03-06T21:39:29.341Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><title type='text'>Ubuntu - First Impressions</title><content type='html'>I downloaded the latest ISO image of &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu&lt;/a&gt; a few days ago, and tonight I finally got around to burning it to a CD so I could actually use it.&lt;br /&gt;&lt;br /&gt;For those of you that don't know, Ubuntu is a Linux distribution focusing on usability.  I guess the aim is to tempt people across from their Windows PCs by giving them something that's as simple to use but free and more secure.&lt;br /&gt;&lt;br /&gt;Anyway, my limited Linux exposure was about 6 or 7 years ago with Red Hat and SUSE, and although they were relatively easy to get to grips with I didn't think they were ready for the masses.&lt;br /&gt;&lt;br /&gt;Fast forward a few years to Ubuntu, and you get an OS that you don't even need to install if you only want to try it out.  With LiveCD you just run the entire thing from CD so you can try before you commit to installing it.  Old news to some people I know, but the whole "try before you buy" thing is certainly impressive when you're talking about something as complex as an operating system.&lt;br /&gt;&lt;br /&gt;So that's what I've been doing tonight, playing with the LiveCD version to see what it's like.  I'm impressed enough to want to install it put it that way.  I've got a second hard drive and intend to dual boot Ubuntu and XP, the documentation looks pretty straightforward, but I'll write more when the time comes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-8606097808285674231?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/8606097808285674231/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=8606097808285674231' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/8606097808285674231'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/8606097808285674231'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/03/ubuntu-first-impressions.html' title='Ubuntu - First Impressions'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6936260.post-259520590356462011</id><published>2008-03-05T22:27:00.003Z</published><updated>2008-03-10T20:13:01.146Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Comment'/><title type='text'>New Life, New Blog</title><content type='html'>Tomorrow marks my last day as an employee of Esendex, and as &lt;a href="http://devproj20.blogspot.com/"&gt;my previous blog&lt;/a&gt; was set up solely to demonstrate what work I was doing there I thought I should go back to this personal one and reinstate it.&lt;br /&gt;&lt;br /&gt;So, as I continue with my life and career I'll be adding new posts here along the way.  I shouldn't think I'll be maintaining my old one, although I'll leave it there for reference as I gather there are links to some posts that some people have found useful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6936260-259520590356462011?l=iandykes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iandykes.blogspot.com/feeds/259520590356462011/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6936260&amp;postID=259520590356462011' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/259520590356462011'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6936260/posts/default/259520590356462011'/><link rel='alternate' type='text/html' href='http://iandykes.blogspot.com/2008/03/new-life-new-blog.html' title='New Life, New Blog'/><author><name>Ian Dykes</name><uri>http://www.blogger.com/profile/08235675789374664427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
