Thursday, February 12, 2009

Prefer IEnumerable<T> to IList<T> for Public Members

A coworker of mine knew vaguely of my preference for IEnumerable<T> over IList<T> for exposing collection members of a class. He needed to expose a collection and its count somehow, and asked me what I thought. Here it is:

I prefer IEnumerable<T> to IList<T> for the following reasons.

IEnumerable<T> is the lowest common denominator of collections, but still very useful as it is foreachable.

Because it is the lowest common denominator, my backing collection can be any number of specific collection types, including an array.

It is easy to return an empty, ad hoc, 'light-weight' enumeration: Enumerable.Empty<T>().

I can even not have a backing collection, and instead implement the enumeration in code using the yield keyword.

IList<T> has methods like Add() and Insert() and in most API situations I don't want clients adding members to my collection - IEnumerable<T> is immutable.

IEnumerable<T> is easily managed by Linq extension methods, e.g.

IEnumerable<IWidget> widgets = someObject.GetWidgets();
int count = widgets.Count();


Note that Count() is a method, not a property. It is an extension method (C# 3.0) that you have access to when you use System.Linq. The implementation, which you can see in Reflector, amounts to foreaching over the enumeration and incrementing a counter. It is efficient as it can be and we don't have to write it over and over.



It is simple to get an IEnumerable<T> into a List<T>:



List<IWidget> widgetList = new List<IWidget>();
widgetList.AddRange(widgets);



IEnumerable<T> is very composable - the new Linq extension methods allow you to do all sorts of magic with them - filtering, sorting, grouping, aggregation all chained together in a single line of code. IList<T> gets that too because it descends from IEnumerable<T>, but its pretty cool that the lowest common denominator collection gets this stuff.



The most persuasive argument is the one regarding clarity of the API. In every case I can think of, a collection property should present immutable interface, and IList<T> is mutable. If I thought I had a scenario where the client should be able to futz with my internal collection, I'd revisit my design because I probably have it wrong. IEnumerable<T> wins because it is clearly immutable.



There are alternatives that permit an IList<T> implementation that doesn't permit appending or inserting, but they're liars. For example List<T>.AsReadOnly() returns a ReadOnlyCollection, which implements IList<T>. But it lies. It has Add() and Insert() methods, but they always throw NotSupportedException. For me, it's a non-starter because the interface is misleading.



You could also just return a copy of your internal collection, something like this:



public IList<IWidget> Widgets
{
get
{
IList<IWidget> temp = new List<IWidget>();
temp.AddRange(_widgets);
return temp;
}
}


But I think this is just as misleading. Sure, you can honestly add and remove items, but it implies that it is the internal collection when it really isn't. Again, IEnumerable<T> wins because it makes the API clearer.



You may have a nagging concern that you are getting your Count by iterating through the enumerations rather than having and storing it somewhere. I wouldn't worry about it. It all the cases I can think of, this is trading cycles for clarity in the API. Clarity always trumps performance until we know or at least have a realistic expectation of a performance issue.

But even then, you needn't worry. Because wherever possible, these extension methods on IEnumerable<T> try cast it to a higher level collection to optimize the code. So the Count() extension method tries to cast the target to ICollection<T> so it can use the Count property. Only if it can't do that does it actually iterate through the enumerable to get the count. Check it out in Reflector.



IEnumerable<T> is a clear first class citizen with the addition of all those nifty new extension methods in System.Linq. And even without those, it should be the first choice for exposing an immutable collection.

Thursday, January 29, 2009

Clean Code

One of my refrain's at the recent SoCal Code Camp was "Simple Code."  I was inspired by Scott Bellware's recent appearance on Hanselminutes where he equated simplicity with easy testability.  It is a great podcast, and highly recommended.  Ultimately the point is that we want the code we touch to become more simple.  That is, more easy to understand, more easy to explain, more easy to change and more easy to test. 

CleanCode  Well, Robert C. Martin (Uncle Bob) recently published a new book called Clean Code: A Handbook of Agile Software Craftsmanship which seems to be concerned with similar themes.  I'd had it on my radar since Uncle Bob did a .NET Rocks a few months ago but hadn't gotten a copy yet.  There's always more books than I have time for, particularly lately.

But after my code camp sessions, Vladimir mentioned that he was participating in a study group going through Clean Code.  I had never heard of programmers doing such a thing, but it sounded great.  I liked the notion of the added accountability that comes of joining a group project.  "Hmmm," I thought, "that might be a great way to really learn a book." 

A couple of days later when I asked Vladimir to let me know how the study group went, he surprised me with an invitation to join.  So I went out and got a copy and started in on it. 

My first 'meeting' was today, over the phone.  And it was great.  The whole conference call thing isn't real high on my list, but the book is solid and the discussion really added to it. 

One meeting down and I think this has real promise.  Uncle Bob is great, but Uncle Bob supplemented by a roomful of experienced software developers is a real treasure.

So I'll be attending, every Thursday at noon.  Since I want to make sure I keep up my end of the discussion, I'll be taking copious notes as well.  I'd like to find some way to turn them into blog posts too.  so stay tuned and see what unfolds.

Monday, January 26, 2009

SoCal Rock and Roll Code Camp 01/2009

Thanks to all of you who made it to my Dependency Injection sessions at the code camp.  I really enjoyed doing the presentation.  This was the third time I've presented this stuff and I've finally got the content into the neighborhood of where I want it, so I'm particularly satisfied. 

I've gotten my slides cleaned up and saved off my sample code so I can post it on the code camp website.  You can download slides and sample code for each session from its page.  Here they are: Dependency Injection - Why Bother and Fun with Dependency Injection Containers.

I promised some links as well.  Here they are:

Google Testing Blog - This is a great blog with vast amounts of solid practical advice.  It is focused on Java rather than C#, but in most cases that won't be a problem.  The principles are pretty much the same. 

Particularly recommended here is the Guide: Writing Testable Code which appears to be the standards Google uses in code reviews.  It is full of specific guidance and before and after examples both of code and unit tests.  Again, mostly Java, but for the most part it shouldn't be a problem for C# developers.

The StructureMap site is full of good guidance on Dependency Injection Containers in general as well as StructureMap in particular.

You can find more about Autofac at Google Code.  The wiki is a good source of guidance for Autofac's various features.  Assuming the lambda syntax doesn't still make your brain hurt the samples are pretty easy to comprehend.

Don't forget Castle Windsor.

I spent a lot of time on the Single Responsibility Principle and the Open/Closed Principle.  Robert C. Martin's (Uncle Bob) original articles are available from his web site:  SRP and OCP.

Finally, a few great books:

Agile Principles, Patterns, and Practices in C#

Working Effectively with Legacy Code

Refactoring: Improving the Design of Existing Code

As I said in the sessions, feel free to contact me if you have a question you think I can help you with.  It is a big topic.

Thank you again for attending.  I had a lot of fun. 

Tuesday, October 28, 2008

LA Code Camp Materials - They're Here!

Okay, the Code Camp site is back up and I've been able to upload my code and slides.  If you need a hand with any of it let me know.  Here are direct links to each session's page.

Dependency Injection - Why Bother?

Fun with Dependency Injection Containers

In addition to the materials, there is a feedback button.  I'd really appreciate it if you'd give it a click and fill it out - it won't take more than a minute.

Thanks again.

LA Code Camp Materials Part II

You're probably thinking that this is the post where I say I've finally posted the sample code and slides.  From the Code Camp last weekend.  And maybe ask you to complete the evaluations online? 

I thought it was too, until I discovered that the Code Camp site was down.

So maybe Tuesday isn't in the cards.  Wednesday perhaps?

If anyone is desperate for the materials (which would be surprisingly nice) leave a comment and we'll figure something out. 

But don't leave an email address unless you have a really good spam filter.

I'll try again later today.  Thanks for your attendance and your patience.

Monday, October 27, 2008

LA Code Camp Materials

Thanks again to all of you who attended my sessions at the Code Camp over the weekend.  I had fun giving it - and the discussion was great.

I'll be posting slides and sample code on the Code Camp web site sometime on Tuesday - sorry about the delay.

Thanks again.

Wednesday, July 23, 2008

TDD Guidelines

Heard a nice short podcast from NetObjectives on impediments to TDD this morning.  I had to register to get to it, but it doesn't cost anything.

They considered the problems associated with TDD adoption.  One which struck me in particular is the problem of many tests breaking when a minor change has been made.  This tends to push developers to 'temporarily' ignore tests so they can get their work done.  Which often becomes more than temporary.  I know I've built up a test maintenance burden this way.

They addressed this by defining a "good" unit test as follows:

  1. A unit test should fail always for a well understood reason.
  2. A unit test should never ever fail for any other reason.
  3. No other unit test should fail for that reason.

Well, I'm guilty. 

Sometimes I get going on writing unit tests without being mindful of my 'well understood reason' just for the sake of hacking out tests.  This is a nice formulation for me to keep in mind.

xUnit Test Patterns has a lot to say about this kind of thing too.

Tuesday, July 01, 2008

Dependency Injection Resources

Here are the promised resources:

The Single Responsibility Principle by Robert C. Martin (Uncle Bob) is one of the design principles that makes Dependency Injection useful.  Also recommend are his articles Open/Closed Principle; Dependency Inversion Principle; and Liskov Substitution Principle.  All of these articles are more or less excerpts from his book Agile Principles, Patterns, and Practices in C#, so if you are interested in his book (which is great) these articles would be a good place to start before you make the investment.  Remember there is a Java version of the book too (Agile Software Development, Principles, Patterns, and Practices).

Unfortunately due to the structure of my talk I gave these principles short-shrift, so I want to make myself clear while I have the chance:  I consider them to be more important than the tool (the container).  In fact, I suspect that if you aren't following SRP, OCP and DIP, a Dependency Injection container would be useless anyway.

While I'm on books, Refactoring: Improving the Design of Existing Code is a must have title.  This is the book I mentioned in the talk that I bought years after having it recommended.  It was too bad I waited, because the book was a revelation.  Just the chapter on Code Smells alone is worth the price of admission.

The Castle Project's home page is a link worth having.  There are some tutorials worth looking at here if you want to go deeper.  Note that the Castle Project is a lot bigger than just the MicroKernel and Windsor Container - it also boasts the Monorail project (a .NET MVC web framework) and a really cool Dynamic Proxy.   Great stuff.

Using Castle Project is a collection of Castle Windsor specific resources. 

I'm not actively using StructureMap right now, but they just had a new release that is probably worth looking at.  They also have a NAnt task for testing configuration, which is a really cool addition.

High-Level Concepts is a part of the StructureMap web site which gives some great summaries of concepts surrounding good design in general, and Dependency Injection in particular.  These are important regardless of which container you use.  It was written by Jeremy Miller, who's blog is a great resource no matter what he's talking about.

The IoC mind set: Validation is a pretty powerful article by Oren Eini on how to use a Dependency Injection Container (Castle in this case) to manage a multiplicity of validation rules.  It addresses a point I had hoped to make with my final example but which got lost in the lack of time and the broken code.  The container permits some *very* interesting efficiencies, that you just wouldn't come up with if you didn't have a container.  It is what Oren calls the Inversion of Control Mind Set in this entry.

I'd recommend subscribing his blog if you really want to stretch your mind in this direction.

ALT.NET Portal is a good place to start for exposure to all of the ALT.NET stuff, not just Dependency Injection.  The discussion groups on Yahoo are pretty rich.

Inversion of Control Containers and the Dependency Injection pattern is Martin Fowler's article on the topic.  It is usually the first citation when someone covers this topic.  It examines an alternative pattern as well - Service Locator.

Again, if any of you want further assistance with this stuff, call or email me and I'll be glad to help.  Thanks again for attending!