Tuesday, March 18, 2008

.NET Readonly Collections & LSP

Chad Myers has a post on LSP, the example isn't technically of LSP (see comments) but it did make me think of one of my pet peeves in the .NET framework.

As you may know you can call List<T>.AsReadOnly and get back a read-only wrapper, you get back an object that supports IList<T> so you try to use it:

List<string> dinosaurs = new List<string>();
ReadOnlyCollection<string> asReadOnly = dinosaurs.AsReadOnly();

((IList<string>)dinosaurs).Add("Tyrannosaurus");
((IList<string>)asReadOnly).Add("Bob"); // kablam, NotSupportedException

Now looking at the documentation the exceptions are made clear, for example on ICollection<T>.Add. This means that it's not an LSP violation, but it does annoy me because it means that most of the methods on IList<T> will raise exceptions if they are not suitable for use with the actual type behind the interface.

And remember this could be a real problem. For example your method had been accepting List<T> and had been calling Add on that class. You decide that its nicer to use base types where possible so you change the method to accept IList<T> and now your open to being passed a ReadOnlyCollection which will immediately blow up.

So why is the design the way it is, dunno. Does seem like it was discussed but it's not a decision I like. I'd have probably had a specific IReadonlyCollection<T> interface. In fact we have that interface in our code base and we've found it very useful indeed, particularly in the domain where we want to make clear when things are read-only without having to resort to exceptions.

If you don't know what LSP is then read this PDF or even this link (which I found whilst searching for the PDF) but really to get your head around a lot of this stuff you need to go to the books, in particular Agile Principles.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

2 comments:

  1. Anonymous1:50 pm

    Hi Colin,

    I was just wondering how thing were going for you since our last meeting (8 years already) ...

    Still living at Edinburgh ?

    I couldn't find your email addresse so i just send you my gmail adress through this blog (sorry) : sunn3000@gmail.com

    Contact me there when you have time. I would be happy to have some news from you...

    Fred GUIOT
    Cadenet
    France

    ReplyDelete
  2. I personally avoid exposing readonly collections in favor of things like an IEnumerable(of T) (stupid thing thinks < is HTML) ... you can always put my Ienumerable in a collection but its less leaky as to how I deal with it internally.

    ReplyDelete