by skeet via Jon Skeet's Coding Blog : C# on 3/2/2008 7:54:44 PM
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.
MoveNext()
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.)
as
InvalidCastException
NullReferenceException
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:
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 :)
yield do
yield
do
begin
initial
fixed
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.
Original Post: C# 4 idea: Iterator blocks and parameter checking
The content of the postings is owned by the respective author. CSharpFeeds is not responsible for the contents of the postings. This site is automatically generated and cannot be reviewed for abusive content. If you find abusive content on CSharpFeeds, please contact us. Designated trademarks and brands are the property of their respective owners. All rights reserved.