C# 4 idea: Iterator blocks and parameter checking

Iterator blocks have an interesting property: they defer execution. When the method (or property) is called, none of your code is executed – it only starts running when MoveNext() is first called.

Deferred execution is a great thing in many ways, but it’s a pain when it comes to parameter checking. If you check parameters within an iterator block, you’ve effectively left a timebomb – the error will be potentially reported a long way from the original source of the problem. (Side-note: this is why I prefer using a cast to as when I know what type something really should be – I’d rather get an InvalidCastException immediately than a NullReferenceException later on.)

One solution to this is to check the parameters in the public method and then call a private method which is implemented with an iterator block. That’s a bit ugly though. It would be nice to be able to specify the parameter checking in an initial block which could only occur at the start of the method – something like this simple implementation of Repeat:

I’ve chosen yield do for two reasons: it fits in with the rest of the yield pattern, and by using an existing keyword I suspect it reduces/eliminates the chance of this being a breaking change. It’s not ideal from the point of self-description, but do is the closest keyword I could find when I looked at the spec. In a language with begin as a keyword, that would probably be a better choice – or initial. fixed appeals in that the code is fixed in the method rather than being shunted off into the compiler-generated type, but the normal use of fixed is far too different to make this an appealing choice. Any other suggestions are very welcome :)

Is this an important enough change to make it worth including in C# 4? I’m not sure. The negative side is that I suspect relatively few people use iterator blocks much, so it may not have a very wide benefit. The positive side is that it only actually makes any difference to those who do use iterator blocks, and I believe almost all of them would find it a welcome addition. It’s simple to understand, and it makes iterator blocks much easier to use in a “correct” manner when any form of initial checking is involved.

Note, mostly to myself and Marc Gravell: I haven’t checked, but I suspect most of Push LINQ is broken in this respect.

Further note to self – I really need to fix my code formatter to treat yield as a contextual keyword.

Neil: using the Spec# approach certainly makes sense if contracts like this make it into the main body of the language. I don’t think I’d want them to be introduced *just* for iterator blocks though. Of course, one problem of implementing my proposal (without Spec# contracts) is that if contracts are added later, my syntax becomes obsolete.

On the other hand, it’s possible that there are other things which *might* make sense to do immediately, beside parameter checking. Logging is the only one I can think of immediately…

Jared: I seem to remember there’s a good reason for the second part of a “yield-statement-phrase” being a keyword. I can’t think of any ways in which “yield validate” followed by a block would be valid code, but “yield validate;” certainly would be if you had a type called yield. Using a keyword as the second part prevents that situation.

Fortunately, this kind of detail is one for the language designers, if they decide to go with the idea at all. (I strongly suspect it’s an idea which has come up before – I’m not daft enough to think I’m likely to invent genuinely original concepts in this area.)

Imagine they didn’t defer execution, and examine a LINQ to SQL example which contains multiple method calls (Where, Select etc). If each method call had to operate immediately, you would never get the benefits of LINQ – you wouldn’t get the whole query translated into SQL, you’d get one part at a time.

For instance, if you do a join and then a where, you’d end up getting the whole contents of the join back from the database – far from ideal!

Likewise deferred execution is necessary for streaming. Imagine if (in LINQ to Objects) Select had to execute immediately. It would have to store the data somewhere, making a copy. Because it only actually fetches data when it’s asked for it, it is able to only process data as it flows through.

Sorry, that’s not terribly clear – but I suspect if you think about it further, you’ll get it. Just imagine trying to write it in a non-deferred fashion, and then see how evil the whole thing gets.

There are enough “one-off” solutions in C# already. It would be much better to introduce a general construct that allow clearly specify contract. And it would be even better if this construct would be part of the method specification and not of the method body. I. e. it should be possible to include it into declaration of the methods in interfaces as well as into declaration of delegates.