views:

142

answers:

3

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?

+1  A: 

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.

FlySwat
Thanks, I think it's the only right way to go in my situation.
Sorskoot
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.
Robert Rossney
A: 

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);
  ..
}
Cristian Libardo
Thank you for your comment. In my case yield isn't an option. But I shall keep it in mind, it could be usefull...
Sorskoot
+1  A: 

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);
}
Mark Brackett