Thursday, October 2, 2014

Cowboys vs Perfectionists vs … Body Builders

I've worked with many developers over my fifteen years of professional software development.  Sometimes I just can't help but classify them.  But I bet you've noticed this too: there tends to be two main types.

Cowboys


If you've never heard of unit testing or avoid it because it slows you down, you're probably a cowboy.  Cowboys can prototype concepts to prove viability before you've finished describing the idea.  They can hit unrealistic deadlines and still have plenty of time to gold plate.  A cowboy is guaranteed to get you to market before your competition.  But God help you if you put their code in the hands of end users: you'll have more bugs than a bait shop.

Perfectionists


If your goal is 100% code coverage, you only code TDD, or you spend more time refactoring than producing customer-centric code, you might be a perfectionist.  Perfectionists write pristine, maintainable, refactorable, low-defect code.  Applications built by perfectionists will last the test of time.  The problem is it'll take them twice as long to get to production as it should and if their project doesn't run out of money first, their competition is liable to beat them to market, invalidating all that beautiful code.

Body Builders


Quick quiz: how do the most successful body builders maximize muscle mass while minimizing body fat?  Steroids of course.  Ok, how do they do it legally?  Maximizing muscle mass takes lots of lifting, lots of protein, and lots of calories.  Minimizing body fat requires cardio work and dieting.  But dieting and consuming calories are mutually exclusive.  So the answer is that body builders alternate between periods of cutting (dieting) and bulking (eating and lifting).  Neither activity alone will allow them to reach their goals.

Cowboy + Perfectionist = Cowfectionist?

So what do body builders have to do with software developers?  A fantastic software developer I once worked with used to say he felt software developers should be paid based on the lines of code they delete.  I always enjoyed his deleting code theory (clearly he was more of a perfectionist than a cowboy), but it struck me recently that deleting (refactoring) is to writing code as cutting is to bulking.  In other words if you try to do one exclusively, or (worse) both simultaneously, you're setting yourself up for failure.

Summary

We all have tendencies toward cowboys or perfectionists, but to become the most successful software developers our goal should be to alternate between cutting and bulking, refactoring and producing.  Obtaining a high muscle, low fat code base that gets to market on time with high maintainability requires neither a cowboy nor a perfectionist: it requires  avoiding extremism, embracing moderation, and recognizing the strengths of those different from ourselves.  If we can find that balance we can truly accomplish great things.

Tuesday, September 9, 2014

My Humbling Week as a Machinist

A terrible ripping noise followed by a clang and a bang echoed through the metal shop.  Everyone turned to look at me.

The bang could have been my last heart beat as I destroyed a machine that costs over $10,000.  Or it could have been a razor sharp bit cracked in half spinning through air and deflecting off my skull.  

In reality it was my the sound of the machine making an emergency stop as I hit the big red button reserved for emergencies.

Developer to Machinist

I got to this point with a goal, a chunk of time, insufficient respect for a new field, and perhaps a touch of hubris.

The goal seemed simple enough: build an aluminum mold for an injection molding machine to help mass produce a part I needed for my hobby.

I was to accomplish this goal at Techshop, a maker group that provides access to tools, information, and an awesome community.  And I was to accomplish it in a week during a vacation.

The general process I used was:

  1. Design the part in Autodesk Inventor
  2. Prototype on a 3D printer
  3. Design the mold in Autodesk Inventor
  4. Design the machining (CAM) operations in an Inventor add-on called Inventor HSM
  5. Export the CAM operations to GCode and import them into a TorMach CNC Milling Machine
  6. Run the cutting operations on a couple of pieces of aluminum (a top and bottom)
  7. Run the injection molder
Autodesk Inventor

Autodesk Inventor is an amazing CAD package that normally costs over $7,000, but as a TechShop member, not only do you get access to a fully stocked metal shop, and just about every piece of machinery imaginable, but you get a copy of Autodesk Inventor.  Fortunately the help documentation and tutorials are excellent and designing a simple part wasn't too hard.


From there I used a Makerbot Replicator 2 to 3D print a prototype and iterate a couple of times on the design.  The part, in case you're wondering will be a cap for the led column on a Siren of Shame, but it's really just an excuse for me to fiddle around and learn machining.




Mold Design

With a TechShop class on mold design I learned the key pieces of information I needed to make the mold including how to:

  • Create a sprue that the molten plastic will be injected into
  • Multiply a single part multiple times (and maintain the link to your part so you can theoretically change it)
  • Create a runner system to distribute molten plastic to the parts
  • Build gates to inject the molten plastic into the parts
  • Design vents that allow air, but not molten plastic to escape
  • Add cold slug wells to keep gasses and sediment out of your mold parts
  • Add registration pins that keep the two halves of the mold (cavity and core) aligned
  • Design your part to be easily injectible (add draft angles and fillets to every surface)


Inventor HSM

Inventor HSM is an amazing plug in for Autodesk Inventor that allows creation of 2.5D and 3D CAM operations for CNC milling machines directly from your Inventor models.  Unfortunately it's pretty new, the documentation is a little weak, and there aren't any TechShop classes on it yet.  Worse, if you don't know what you're doing many of the default cuts won't be correct, to potentially dangerous effect.  


Milling

Everything is so nice and easy right up until you have razor sharp cylindrical blades spinning up to 5,000 RPM and automatically moving along a path that you may or may not have defined correctly.

I ran my first cuts in foam to validate my approach, gain practice with the TorMach CNC milling machine, and get experience with the wide range of bits I would need (including traditional end mills for surfacing, ball end mills for runners, an end mill with a taper for draft angles, and a couple of micro bits for air channels and such).


Unfortunately, my confidence increased after I ran through my cuts in foam.  Foam, it turns out, is completely different from aluminum.  Here's a video of my first disaster.




The surfacing was fine, but I was taking too aggressive of cuts.  After a kind "Dream Consultant" at TechShop explained my mistake I was able to correct it like so (notice the difference in how the machine sounds):

 i

Unfortunately I didn't learn that lesson until after breaking a bit, a collet (bit holder), and embarrassing the heck out of myself in front of a small audience.

Lessons Learned

Throughout my milling time (30+ hours) I made numerous mistake.  Anyone with woodcutting experience (or machining common sense) will probably find these mistakes amusing.  I hope others may find this list constructive:


  • End mills only cut up through where the flutes end.  You can't run a mill into aluminum above that line without bad results.  And for goodness sake don't run the collet (the thing that holds the bit) into your aluminum or even worse things happen.
  • When bits break they go flying really fast and scare the crap out of you and it's loud and everyone in the room comes over to publicly shame you.
  • Even if you're cutting with the blades of your bit you should only mill a small amount of height of aluminum at a time (1/2 the bit width max) otherwise the drill makes a bad cut and terrible noises and you risk breaking the bit.
  • End mills (the ones with an L shape) aren't for drilling.  If you do this then miniscule aluminum shreds will bind to the bit and fling around and create an invisible shield that will block the flow of coolant generating smoke, risking overheating and damaging your bit and the aluminum.
  • Design everything in your part with specific bits in mind.  It's way too easy to design something on the computer that will be nearly impossible to machine.  Going back and modifying your part after you've designed your cuts in practice is extremely hard.
  • Getting your X, Y, and Z coordinates zero values correct on the machine is kinda important. If you get Z wrong, even a few hundredths of an inch too high for example, your cuts will be in air and you could waste a lot of machine time and not be able to tell because the area is flooded with coolant.


But as the kind staff reminded me, we are here to learn and we all have to start somewhere.

The good news is I never damaged the machine (it's actually quite forgiving), I only broke one bit and one collet, and most importantly I didn't (significantly) injure myself or anyone else.

Summary

In the end I successfully milled my pieces, finished them, ran a couple of runs on the injection molder (still some work to do there as you can see below), and ultimately accomplished my goal.



All in all trying on a completely different hat for a week was both fun and rewarding.  Building something real was a blast.  I learned a ton.  But to tell you the truth as thrilling as it was to accomplish my goal, I'm just as thrilled to be headed back to a job where a screw up won't injure anyone or damage a ten thousand dollar machine.  I'm happy to be headed back slightly smarter, happier and more humble.

Tuesday, July 15, 2014

Raspberry Pi Powered Siren of Shame via Node.js

I picked up a Raspberry Pi this week and had fun connecting it to a Siren of Shame.  Naturally the Model B+ with 4 USB ports came out the day after mine arrived.  Regardless, I had fun setting it up.  If you're interested in trying it too here's what to do.


Getting Started


You'll need a Siren of Shame device and a Raspberry Pi that's running and connected to the Internet.  Element14 has a great getting started set of videos if, like me, you're completely new to Raspberry Pi.  I used the Raspbian OS, but theoretically it shouldn't matter what OS you use.

libusb


Libusb provides an API for applications to interface with USB devices, including Human Interface Devices (HID) such as the Siren of Shame.  To install libusb use apt-get (the universal Linux installer).

If this is a new Raspberry Pi with a fresh install of Linux then you will need to update your list of available packages with

sudo apt-get update

Follow that up with:

sudo apt-get install libusb-dev

You should now be able to run lsusb from the command line to list devices.  Plug in a Siren of Shame, run lsusb, and you should get a device with an id of 16d0:0646 called GrauTec.  It should look like:

lsusb

...
Bus 001 Device 011: ID 16d0:0646 GrauTec

If your device doesn't show up, it could be an issue with the cable.  Andy Lowry, who has an excellent blog post where he lights up his siren of shame when freight trains are near, reports that he had to try several cables before finding one that worked.

Node.js


Thanks exclusively to Joe Ferner and his node-sos-device project we have a solution for connecting Siren of Shame's to linux using Node.js.  To install Node.js it should be as easy as:

sudo apt-get install nodejs
sudo apt-get install npm

Incidentally, rather than using node-sos-device directly, we will be using Joe's higher-level node-sos-client, which knows how to monitor Jenkins and Bamboo CI servers.

Node-sos-client


If you haven't configured your device to work with git you could do it the right way with SSH and generate an ssh key or you could just:

git clone https://github.com/AutomatedArchitecture/node-sos-client.git

and

cd node-sos-client

Next you'll need to download all Node dependencies.  If this is a fresh install you'll need to tell the node package manager (npm) where to retrieve dependencies from:

npm config set registry http://registry.npmjs.org/

Now you can install all dependencies for node-sos-client by running

npm install

Upgrading Node


For some fortunate users (Andy Lowry for one) installing node via apt-get works fine.  If, however, you get an error about node being out of date you'll have to uninstall, download, and update your path.

First, to uninstall the old version of node:

sudo apt-get remove npm
sudo apt-get remove node

No download and unpack:

cd ~
wget http://nodejs.org/dist/v0.10.2/node-v0.10.2-linux-arm-pi.tar.gz
tar -xvzf node-v0.10.2-linux-arm-pi.tar.gz

To add it to your path

nano .bashrc

And add the following two lines at the bottom:

NODE_JS_HOME=/home/pi/node-v0.10.2-linux-arm-pi
PATH=$PATH:$NODE_JS_HOME/bin

If you restart your command prompt and type node --version you should get v0.10.2.

Now retry npm install.

cd node-sos-client
npm install

And you should be good to go.

Running node-sos-client


First make a copy of the default configuration file:

cp config.json.example config.json

We'll configure it correctly later.  Next pick up the dependency on node-sos-device by running:

npm install sos-device

To run the app you should be able to run

sudo node build/sos-client.js

However, if you had to install node with the wget method, then you'll need to run

sudo $NODE_JS_HOME/bin/node build/sos-client.js

If you're lucky you'll see the app print out the device stats as json and a configuration error, something like:

deviceInfo: { version: 1,
  hardwareType: 1,
  hardwareVersion: 1,
  externalMemorySize: 0,
  audioMode: 0,
  audioPlayDuration: 0,
  ledMode: 0,
  ledPlayDuration: 0,
  ledPatterns:
   [ { id: 2, name: 'On/Off' },
     { id: 3, name: 'Fade' },
     { id: 4, name: 'Chase' },
     { id: 5, name: 'Fade Chase' } ],
  audioPatterns:
   [ { id: 1, name: 'Sad Trombone' },
     { id: 2, name: 'Ding!' },
     { id: 3, name: 'Plunk' } ] }
Failed to poll: bamboo0 { [Error: getaddrinfo ENOTFOUND] code: 'ENOTFOUND', errno: 'ENOTFOUND', syscall: 'getaddrinfo' }

However, if you have a cable that doesn't work well, or are connecting through a non-powered USB hub you may see:

Error: usb_detach_kernel_driver_np: -113 could not detach kernel driver from interface 0: No route to host

In this case try experimenting with the way you connect the device to the Pi.

Configuring the Connection

Today node-sos-client can connect to two CI servers: Bamboo, and Jenkins.  To connect to Jenkins update the config file to something like:

{
  "builds": [
    {
      "type": "jenkins",
      "config": {
        "url": "http://127.0.0.1/jenkins/api/json/",
        "username": "[username]",
        "password": "[password]"
      }
    }
  ]
}

And you're done.  With any luck running sudo node build/sos-client.js will light the siren and sound the speaker on initial connection, and whenever the build breaks.

Summary


I hope you've enjoyed and are now on your way to terrorizing your build breaking colleagues, even when you're not at the office.  Enjoy!

Monday, June 16, 2014

App for the Windows.Launch contract failed with error: The app didn't start

If you're developing a Windows Store app and you get the error:

...App for the Windows.Launch contract failed with error: The app didn't start

in the following Event Log:

Applications and Services Logs\Microsoft\Windows\Apps\Microsoft-Windows-TWinUI/Operational

The error may be caused because you attempted to install your app via a dism installation and then attempted to deploy it via F5 deployment in Visual Studio.

To verify this is the case you can run:

dism /online /Get-ProvisionedAppxPackages

If you see your app listed you can then remove it with:

dism /online /Remove-ProvisionedAppxPackage /PackageName:[packagename]

You don't even need to log out and log back in.  Hope that helps someone somewhere.


Wednesday, February 19, 2014

Six Techniques for an Effective Retrospective


If a non-agile team were to adopt one single agile technique, what would it be?

My answer, without a doubt, is a regular retrospective.  Why?  An effective retrospective allows you to continually improve your process.  It allows you to add in the other Agile techniques, gradually, as your team is ready for them.  Over time it can be the gateway to a fully agile process that is completely customized for your team.



But there is a fine line between an effective retrospective, and a gripe session that that fails to lead to process improvement.  These six techniques can help you get the most out of your retrospectives.

1. Prepare items before-hand


One of the most important steps for an effective meeting is to have a clear agenda.  Asking team-members to prepare retrospective items ahead of time lays an specific agenda which facilitates:

  • Allocating an appropriate amount of discussion time per item
  • Producing more well thought out, higher quality suggestions
  • Knowing when the meeting is over

2. Centralize items in a repository


Specifying a central location such as a Google Docs spreadsheet or a SharePoint list that team-members can add to as items occur to them can further increase meeting effectiveness.  Not only can team members see and prepare to respond to other team members, but it represents a history of changes, and can provide more structure in entering items.

3. Identify problems and solutions


Unstructured retrospective items submitted by team members seem to come in one of two forms:

  1. Solutions in want of a problem; and 
  2. Problems without a clear solution 

Both types of submissions aren't necessarily bad, but they can lead to ineffective process changes or long discussions that fail to result in meaningful change.

The most effective retrospectives I've seen ask team members to present both a problem and a solution.  By separating off the two sides of the coin the group can decide as a team if there are perhaps better solutions that fit the problem.

4. Revisit old solutions


If a team member has identified a problem and the group has arrived at a process change, how can the team be sure that the solution fixed the problem?

The best approach is to have the team revisit old unresolved items at each retrospective.  If the solution solved the problem, resolve it.  If not, postpone for another meeting or propose another solution.

5. Focus on process, not individuals


Invariably person X will do something to upset person Y.  Then Y will want to bring the issue up at the retrospective.

Having a problem/solution format will help discourage airing personnel issues, but proactive leaders will want to establish some rules ahead of time to encourage team members to work out issues outside of the retrospective to keep the meeting focused on the team's process.

6. What went well


While no concrete changes typically comes from a "what went well" section of a meeting, a pat on the back never hurts, can keep morale up, and can encourage team members to keep doing the good parts.

Summary


With a little extra structure your retrospectives can be shorter, more results-oriented, and more effective.  Why not give these tips a try at your next retrospective?

And if you aren't doing retrospectives?  Schedule your first, you won't regret it.

Wednesday, November 13, 2013

24 Resharper Tips



I firmly believe ReSharper is the best thing to happen to .Net since Visual Studio (NCrunch is a close second).  In evangelizing it I managed to convince my program to purchase copies for every developer.  One caveat: I had to train everyone.

So next week I'm doing a ReSharper presentation.  To keep the talk interesting I thought it would be fun to incorporate a game of Bingo with ReSharper shortcuts.  Get five horizontal, vertical, or diagonal shortcuts when mentioned, yell BINGO, get a prize (Siren of Shame mug anyone? :) ).

Five tips times five tips minus a free spot = 24 tips.



So why not make a blog post while I'm at it?  I've been collecting my favorite tips for years now anyway.  So without further ado:

1. Navigate to Class (Ctrl+T)


Man I love this shortcut.  Need to get to the TrippleDesStringEncryptor quickly?  Ctrl+T then type the capital letters "TDSE" and enter.

2. Rename (Ctrl+R+R)


I use this so often it's become muscle memory and I nearly had to look it up.  It works differently in different contexts.  For local variables it works by renaming all usages inline.  For methods there's a quick modal dialog.  For classes there's a modal dialog that even allows you to synchronize the file name.

3. Move to Another File: (Alt+Enter)


This is fabulous when you're in quick-and-dirty problem solving mode, throw a new class in the same file, but want to fix it when you switch back to refactor mode. Just put the cursor on the class name and hit Alt+Enter+Enter.

4. Extract variable (Ctrl+R+V)


I use extract variable almost with the frequency of Rename.  When you switch back to refactor mode after an intense quick-and-dirty coding session extracting literals or variables is awesome.  For instance if you have:

if (!FileInputOutput.Exists(fileName))

You can select everything inside of the if statement, hit Ctrl+R, V, and ReSharper turns it into something lovely and self-documenting like:

var logFileExists = !FileInputOutput.Exists(fileName);
if (logFileExists)

5. Run Unit Tests (Ctrl+U+R)


I've switched to NCrunch for running tests, but if you aren't so lucky Ctrl+U, R is super handy for running all tests in the solution.

6. Rerun Unit Tests (Ctrl+U+U)


This test running alternative is fantastic for when you're working on a single unit test and need to keep running it as you make small changes.

7. Navigate To (F12/Ctrl-Click)


F12 to navigate into a method is nothing new.  ReSharper adds the ability to hold the control key and hyperlink into a method with a click of the mouse.  Even if you're a keyboard person (like me) this shortcut comes in handy from time to time.

8. Go Back (Ctrl+Minus)


Technically a Visual Studio shortcut, but it's so awesome I just had to list it.  I use it constantly if I've just navigated to a method to peek and I want to return back to where I was.

9. Find usages (Shift+F12)


Visual Studio has the ability to find usages of a method, but it pretty much sucks.  If a method is called only once, for instance, ReSharper goes right to the callee without popping up any dialogs.

10. Next/Prev Method (Alt+Up/Down)


I tend to navigate more with F12 and Shift+F12, but zipping down the methods a class comes in handy from time to time.

11. Delete line (Shift+Del)


Again a Visual Studio shortcut, but one I use constantly.  Yayy to deleting code!

12. Convert to LINQ (Alt+Enter)

So subtle, so mind-blowing.  Imagine you have this code:

foreach (var logFile in logFiles)
{
    if (!logFiles.Contains("Test"))
    {
        Console.WriteLine("Found prod file: " + logFile);
    }

}

If you place the cursor over the foreach statement ReSharper prompts you "Convert part of body into LINQ-expression".  And (with Ctrl+R V) like magic:

var prodLogs = logFiles.Where(logFile => !logFiles.Contains("Test"));
foreach (var logFile in prodLogs)
{
    Console.WriteLine("Found prod file: " + logFile);

}

Heck yea!  This refactoring works in a huge number of scenarios.  It boggles the mind how smart the folks at Jet Brains are to be able to convert procedural code into functional code like that.

13. Convert to Ternary (Alt+Enter)


I have mixed feelings on the ternary operator (e.g. "return hateTernary ? avoidIt : useIt").  These feelings closely mirror my mixed feelings on using multiple return statements from a method (use with caution).  To use it on something like this:

public string GetFilePrefix()
{
    if (Message.Contains("Test")) return "Test_";
    return "Prod_";

}

Put your mouse over the if statement, type Alt+Enter, Enter, combine in an Extract Variable and you get:

public string GetFilePrefix()
{
    var isTestLog = Message.Contains("Test");
    return isTestLog ? "Test_" : "Prod_";
}

Better, right?

14. Extract Method/ Property (Ctr+R+M)


Visual Studio has something similar, but ReShaper's shows you a little preview and you can uncheck parameters that you'd like to handle yourself.  I use this constantly.

15. Insert Code (Alt+Ins)


Useful for inserting constructors and overriding virtual methods.  Super-awesome for inserting extremely hard to get correct code like equality members (e.g. you always remember to override GetHashCode and the non-generic overrides and the == and != operators, right?).

16. Make Public/ Private (Alt+Enter)


This shortcut saves typing when you're on public/private/protected keyword, but little known fact: you can also use it on the other end when you're trying to call a method you don't yet have access to.

17. Extract Interface (Ctrl+Shift+R)


I'm not a big fan of interfaces for reasons I'll enumerate another time, but when you do need them the ability to turn a class into an Interface is really awesome.

18. Navigate to Implementation (Alt+End)


If you're living in code that uses a lot of interfaces you probably hate F12 because it takes you to the interface rather than the implementation.  ReSharper and Alt+End to the rescue.

19. Navigate to Base (Alt+Home)


Navigate to Base will take you to an Interface if you're in a base class.  It will also take you to the virtual or abstract method you're overriding if you're in a subclass.  Very handy.

20. Implement Members (Alt+Enter)


Will make you very happy when you need to override an abstract class or interface.  Just put the cursor over the base class or interface and hit Alt+Enter, Enter.

21. Next Warning (Alt+PageDown)


The static code analysis features of ReSharper are legendary.  If the tool finds a lot of issue in a given file you can jump through them quickly with Alt+Page Down or Alt+Page Up.

22. Change Signature (Ctrl+R+S)


How often have you wanted to move a parameter from the Nth position in a method to the first or last? If you're anal like me all the time.  Ctrl+R S saves the day.

23. Un/Comment (Ctrl+K, C or Ctrl+K, U)


Alright, another Visual Studio shortcut, but I'm always surprised at how few people know about this.  Ctrl+K and then C while selecting several lines of code will comment them out.  Ctrl+K and then U uncomments.

24. Surround With (Ctrl+E+U)


Such a nice shortcut for surrounding a block of code with an if statement, using block, or try-catch statement.

Summary

I hope you've found these 24 ReSharper tips useful.  What are your favorites?  Please post in the comments or start a conversation with me on twitter @lprichar.



11/17/13 Bonus Tips
After receiving some great additional tips on twitter and after watching the Resharper Fundamentals pluralsight course I thought I'd add the following three tips:

25. Duplicate Line (Ctrl+D)
Great tip from @g00fygrin, I use this all the time.

26. Locate in Solution Explorer (Shift+Alt+L)
As @therealbennor said this is great when you're jumping around a lot with Ctrl+T and F12. Personally I prefer the "Track Active Item in Solution Explorer" option under "Projects and Solutions", but I know that's not a popular feature.

27. Bookmarks (Ctrl+Shift+1 to set Ctrl+1 to go to)
I learned so much from the Resharper Fundamentals pluralsight course. I can't recommend it enough. This tip in particular made my day. Fantastic for large codebases.

Wednesday, October 23, 2013

Learning C# via Katas - Part 2 - Extension Methods

This is part 2 in a series of blog posts exploring CSharpKatas, a new GitHub project and training tool I put together.  The Katas teach C# newcommers how to apply advanced language features, how to write idiomatic C#, and most importantly how to avoid Java idioms.

If It Types Like a Duck


Kata #1 introduced the reader to LINQ and some replacements for loops and if statements.  Kata #2 focuses on a feature typically found in dynamic languages that allows adding methods to other people's classes without modifying or subtyping the class.  The feature, called extension methods, introduces to C# elements of a feature known as "duck typing" found in languages such as Ruby or JavaScript.

Duck typing is a style of typing in which an object's methods and properties determine the valid semantics, rather than its inheritance from a particular class or implementation of a specific interface. The name of the concept refers to the duck test, attributed to James Whitcomb Riley, which may be phrased as follows:
When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck

Unlike with dynamic languages, however, C#'s extension methods are implemented via some fancy compiler trickery.  The details of the trickery is captured in the third todo in the Kata in which the reader is asked to reverse engineer the Intermediate Language (IL) code after compiling the solution.  This final todo will also add a powerful tool to the reader's toolbelt.

Caveats and Limitations


Due primarily to the compiler trickery mentioned above extension methods have drawbacks over what dynamic language aficionados would likely expect.  For instance isn't possible to add static methods onto other people's classes.  Additionally, one can't add properties to external classes.  This last limitation has frustrated me on more than one occasion.

Another limitation is that extension methods require both knowing the namespace an extension method is defined in, and adding a related using statement.  This limitation can make it hard for others to discover your extension methods.  It can also decrease readability as it can be difficult to determine where a method actually lives.

Finally a caveat: it can be easy to over use extension methods after first learning of them.  For instance just because you could add a SpellCheck() method onto C#'s String class, would you really want this in your code:

foreach (var error in "I'm a bad speller".SpellCheck())
{
    // The above is a bad idea, please don't do it
}

Kata #2


With the caveats and drawbacks out of the way here is a copy of the second Kata:

using System.Collections.Generic;
using NUnit.Framework;

namespace CSharpKatas
{
    // todo #1: Without modifying SomeoneElsesClass add a new class that 
    //     makes the unit tests pass
    // todo #2: Refactor so that there are no loops or if statements.
    // todo #3: (see below)


    #region DoNotModify
    // DO NOT MODIFY THIS CLASS
    public class SomeoneElsesClass
    {
        public List<int> Numbers { get; set; }
    }
    #endregion

    [TestFixture]
    public class TestExtensionMethods
    {
        [Test]
        public void FindNumberOrDefault_NumberExists_ReturnIt()
        {
            var someoneElsesClass = new SomeoneElsesClass
            {
                Numbers = new List<int> { 1, 2, 3 }
            };
            Assert.AreEqual(1, someoneElsesClass.FindNumberOrDefault(1));
        }

        [Test]
        public void FindNumberOrDefault_NumberDoesNotExist_ReturnNull()
        {
            var someoneElsesClass = new SomeoneElsesClass
            {
                Numbers = new List<int> { 1, 2, 3 }
            };
            var v = someoneElsesClass.FindNumberOrDefault(4);
            Assert.IsNull(v);
        }

        [Test]
        public void FindNumberOrDefault_SomeoneElsesClassIsNull_CheckForNull()
        {
            // todo #3: What's bizarre about the following test? Why is there 
            //    no error? Consider reverse engineering the code with a tool 
            //    like Just Decompile to get the answer.
            SomeoneElsesClass someoneElsesClass = null;
            Assert.IsNull(someoneElsesClass.FindNumberOrDefault(4));
        }
    }
}


Summary


I hope you find these Kata's fun and enlightening and that you find my enthusiasm for the C# language contagious.  Enjoy!  And feel free to ask questions in the comments here or @lprichar on twitter.