Let's start with the following snippet:
Foreach(Record item in RecordList){
..
item = UpdateRecord(item, 5);
..
}
The UpdateRecode function changes some field of item and returns the altered object. In this case the compiler throws an exception saying that the item can not be updated in a foreach iteration.
Now the UpdateRecord method is changed so that it returns void and the snippet would look like this:
Foreach(Record item in RecordList){
..
UpdateRecord(item, 5);
..
}
In this case the item would be updated because Record is a reference type. But it makes the code unreadable.
The project I'm working on has lots of foreach-loops with the almost the same code over and over, so I would like to create methods that update parts of the records. Is there a nice way to do this? One that make the code more readable instead of trashing it further more?
-
If you need to update a collection, don't use an iterator pattern, like you said, its either error prone, or smells bad.
I find that using a for loop with an index a bit clearer in this situation, as its very obvious what you are trying to do that way.
Sorskoot : Thanks, I think it's the only right way to go in my situation.Robert Rossney : There's absolutely nothing wrong with using an iterator pattern to update the items in a collection. You don't want to add or remove items from the collection while iterating, and that's what the compiler is complaining about. -
Do you need to update the same list? Could you return a new (updated) enumeration instead?
foreach(Record item in RecordList){ .. yield return GetUpdatedRecord(item, 5); .. }
Sorskoot : Thank you for your comment. In my case yield isn't an option. But I shall keep it in mind, it could be usefull... -
The compiler is complaining that you can't update the collection, not the record. By doing item = UpdateRecord, you are reassigning the iterator variable item.
I disagree that UpdateRecord(item, 5) is in any way unreadable - but if it makes you feel better, an extension method may make it more clear that you are changing the contents of item.
static void Update(this Record item, int value) { // do logic } foreach (Record item in RecordList) { item.Update(5); }
0 comments:
Post a Comment