Page 2 of 2
Best/Simplest way to replace lines of text in a file
Posted: Tue Feb 18, 2020 9:07 pm
by FFF
Hm.
Code: Select all
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"
Best/Simplest way to replace lines of text in a file
Posted: Tue Feb 18, 2020 9:52 pm
by kevclark64
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.
Best/Simplest way to replace lines of text in a file
Posted: Tue Feb 18, 2020 10:40 pm
by Chris
Karl,
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.
Best/Simplest way to replace lines of text in a file
Posted: Wed Feb 19, 2020 1:55 pm
by kevclark64
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:
Code: Select all
For each course in student.courselist
course.startdate=date()
next
I'm assuming that the above code would change the actual object in student.courselist rather than creating a new course object. Is that correct?
Best/Simplest way to replace lines of text in a file
Posted: Wed Feb 19, 2020 4:02 pm
by Chris
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.