FUNCTION Start( ) AS VOID
LOCAL array1[2]
array1[1 ]:="Old line 1"
array1[2]:="Old line 2"
FOREACH cArrayLine AS STRING IN array1
cArrayLine:="This is a new line"
? cArrayLine
NEXT
RETURN
warning XS9064: Cannot assign to 'cArrayLine' because it is a 'foreach iteration variable'
Using X#/FoxPro in Xide
Looking back to my code i recognise, you are right, also in X#/VO i see "only" a warning...
BUT: Adding a "? array1[1]" AFTER your "NEXT" - i see again "Old line 1" !!
@Dev: I don't understand, why you issue only a warning here - "Cannot" != "Should not"
Regards
Karl
(on Win8.1/64, Xide32 2.20, X#2.20.0.3)
You're right. That does issue a warning. I didn't notice it because it compiled and ran so fast I couldn't read the warning before it was gone. But if I set "Warnings as Errors" then it stops and shows the warning and won't compile.
Regarding the original array not changing, it looks like FOR EACH is creating a new variable rather than a reference to the original variable. (FYI I tried it in Foxpro and it did the same thing.) With that in mind, it would clearly be better to use a FOR ... NEXT with a counter and process directly each array element, as you had in your other example.
FFF wrote:
@Dev: I don't understand, why you issue only a warning here - "Cannot" != "Should not"
This is an error message that c# uses, so X# uses the same one. In c#, modifying the iteration variable is never allowed, but since there's no fundamental real problem when actually doing so, and because vulcan did allow it, we made it a warning in X#, instead of an error (and the same has happened with literally dozens of other c# errors!).
But I agree, it should be better to slightly adjust the message itself.
Chris, when the items being iterated are more formally objects (rather than say a string or integer), I'm assuming that properties of the iteration variable can be changed. For example, my main application has students and courses. So, in a case like this:
Kevin, the quick answer would be "yes", but it actually depends on the type of the elements in the collection. If the elements are of a "reference type" (class), then what you get is a var that points (has a reference) to the (each) original element. But if you have a collection of "value type" (structure), then the foreach var only contains a copy of the original element.
So for a List<System.Windows.Forms.Control>, the iteration var of foreach would point to each actual element every time, and modifying a property on it will modify the property in the original element. But for a List<System.Drawing.Point>, the iteration var would only receive a copy of the original element and modifying a property of the var would only affect that local copy.
Maybe this is the reason why it's not allowed in c# to modify the iteration var, because of this possible confusion it could create with reference vs value types.