May 2003 - Posts
A marvellous nugget of comedy PR from the "Implementing Singleton in C#" section on Microsoft's Enterprise Patterns site:
[Sells03] Sells, Chris. "Sealed Sucks." sellsbrothers.com News. Available at: http://www.sellsbrothers.com/news/showTopic.aspx?ixTopic=411.
Note: Despite its title, the "Sealed Sucks" article is actually a balanced discussion of the pros and cons of marking a class sealed.
NMock 1.0 has been released.
Roy has a mini-rant about the use of undocumented features:
"Don't people get that if you use something the way it wasnt supposed to be used, you can get unexpected results, not to mention crashing and other stuff. this is just the kind of stuff VB6 developers were afarid of when trying to do multithreading using API calls. You just [can't] trust it enough to put it in production."
Two points to counter this. First, production code isn't production code without a battery of tests to support it. Whether the code you're calling into is documented or not shouldn't affect your desire to write tests against it. Whether the API you use is "public" or not doesn't mean it is more or less robust than anything else. Sure, public APIs may have been excercised more thoroughly, but in the context of any particular application, the reliable functionality of any code should be defined by the tests it passes.
Second, there is a whole group of applications which relies on this "edge" functionality, namely, tools. I recently wrote a testing tool for ASP.Net which relied on undocumented calls into System.Web classes to do its work, and a method interception tool which has to do all sorts of crazy stuff with metadata and bytecode. Lutz Roeder has written a bunch of incredible tools which excercise the darkest corners of .Net. John Lam likewise, with AOP. There is always a fight between the developers of a framework/language needing to draw a line under the functionality they can support, and pioneering users needing to push the boundaries.
Jonathan asks for clarification on IEnumerator behaviour. No, Reset() is not expected to be called before iteration. When a new IEnumerator is retrieved from GetEnumerator(), it is expected to be positioned at index -1, before the first element of the collection. MoveNext() must then be called to advance it to the first element.
C#'s foreach construct (and VB is probably the same) retrieves a new enumerator from a collection, which is why you can write:
foreach(Foo foo in fooList)
foreach(Foo foo in fooList)
and the second loop will still iterate over all elements in the list. However, if you fetch your own enumerator (maybe you want to save a reference to it as an optimisation), you'll have to call Reset() after a full loop if you want to use it again:
FooEnumerator fooEnumerator = fooList.GetEnumerator();
If you are writing your own IEnumerator, make sure its initial state positions it at index -1.