1

C# Won't allow me to do this.

foreach (Point point in filledPoints)
{
    point.X = 0;
} 

filledPoints is a List<Point> It gives me a compiler error: "filledPoints is a foreach iteration variable, so the associated members can't be edited" (Sorry, the message is in german and im bad at translating). But this works:

foreach (Point point in filledPoints)
{
    Point point2 = point;
    point2.X = point2.X / oldSize.Width * Size.Width;
}   

Why does this not work and is there a more elegant way to bypass it?

Mike Zboray
  • 39,828
  • 3
  • 90
  • 122
Keine Ahnung
  • 111
  • 2
  • 10
  • 1
    The error message tells you exactly why it doesn't work. – Servy Dec 01 '17 at 20:02
  • It just tells me that it doesn't work but not why @Servy – Keine Ahnung Dec 01 '17 at 20:03
  • 2
    I doubt that it tells you `That it doesn't work` also what line does it throw the error on..? do you know how to use the debugger..? if so set breakpoints and tell us the valid error – MethodMan Dec 01 '17 at 20:05
  • @MethodMan It is a compiler error – Keine Ahnung Dec 01 '17 at 20:06
  • tell us what the compiler says exactly also edit the question and show how and where `filledPoints` is defined and what it's type is.. – MethodMan Dec 01 '17 at 20:07
  • 2
    @KeineAhnung what version of Visual Studio/.NET/C# are you on? I cannot find the version that has `" it doesn't work"` as an error message. – maccettura Dec 01 '17 at 20:09
  • @MethodMan done – Keine Ahnung Dec 01 '17 at 20:12
  • @maccettura I'm on .NET 4.6.1 and on Visual Studio Community 2017 (latest updates) – Keine Ahnung Dec 01 '17 at 20:13
  • 2
    @KeineAhnung ignore me, I was being facetious. To try and simiplify: the reason you are getting that error is because you are modifying the value inside a `foreach` (which you are not allowed to do). Normally with reference types its ok to modify properties but `Point` is not a reference type, its a `struct`. So when you are trying to modify a property, you are actually modifying the entire thing. – maccettura Dec 01 '17 at 20:17
  • @maccettura Joeyrp already said that. That makes sense. Is there an alternative class or do I need to create it? – Keine Ahnung Dec 01 '17 at 20:19

2 Answers2

6

This is because Point is not a reference type (it's a struct not a class). So the point variable in the foreach is not actually a reference to the original Point, it is a copy. The compiler doesn't let you modify it because (I assume) it would be easy to think you're changing the original when you are not.

I'm not sure if there's a better way but you could get around this by doing something like this:

for (int i = 0; i < filledPoints.Count; i++)
{
    Point temp = filledPoints[i];
    temp.X = 10;
    filledPoints[i] = temp;
}
Joeyrp
  • 84
  • 4
  • That makes sense. Is there an alternative class or do I need to create it? – Keine Ahnung Dec 01 '17 at 20:18
  • It's a bit messy but you could use a for loop and a temporary Point variable. I'll edit my answer with an example. – Joeyrp Dec 01 '17 at 20:27
  • 1
    @Joeyrp don't remove the code, its the right way of doing it. I would hate for future readers to recreate the poor solution OP went with. As for OP, you should really listen to peoples advice instead of dismissing it. – maccettura Dec 01 '17 at 20:41
1

@Cathal was close. You need to use a for loop like this:

for(int i = 0; i < points.Length; i++)
{
    //This copies the value of the point at the i index into a variable called point
    Point point = points[i];

    //Modifying the point.X property of the copy
    point.X = 0;

    //This replaces the point that is at the i index, with the new point that has the modified X property
    points[i] = point;
} 

Fiddle here

EDIT

I added some comments and additional code to my fiddle to illustrate why your foreach is not working the way you think it does.

maccettura
  • 10,514
  • 3
  • 28
  • 35
  • That was the thing I've already dont with the foreach loop. Thank you but no more help is needed :D – Keine Ahnung Dec 01 '17 at 20:29
  • @KeineAhnung I don't think your `foreach` loop will work the way you want it too. You might want to re-look at my answer. – maccettura Dec 01 '17 at 20:34
  • It works fine with a foreach loop. I just needed to create an own class to store these ints. The other thing was a struct and it gets copied if you store it. @maccettura – Keine Ahnung Dec 01 '17 at 20:37
  • @KeineAhnung why would you write a new class? You already have one that does what you need. Just use the `for` loop like everyone is telling you to. If the struct does what you need then its _way_ faster to use that. – maccettura Dec 01 '17 at 20:37
  • Why you dont understand? `Point` is a `struct`. If you make a new reference of a `struct` the `struct` will get copied. If you change an value of the first reference, it won't change on the second refernce. – Keine Ahnung Dec 01 '17 at 20:46
  • 1
    A `struct` is a value type, so when you create a new variable it _copies_ the existing `struct` values. Then you _modify_ it and re-add it to the list. This is **exactly** what you need to do. You should **not** be making a class that is 1 to 1 with `Point` because you do not understand `struct`. I am trying to explain it to you but you are being stubborn. **Look at the fiddle**. – maccettura Dec 01 '17 at 20:49
  • @maccettura Okay, I give up. I will use your way – Keine Ahnung Dec 01 '17 at 20:57
  • @KeineAhnung You are wrong. The `for` loop solution that literally **everyone** has suggested is the simplest and most efficient way of doing this. We are all trying to help you, but you have shown that you are too stubborn. – maccettura Dec 01 '17 at 20:57
  • 1
    @KeineAhnung the answer you accepted it the right way too. Just dont create your own class. **Use the struct** – maccettura Dec 01 '17 at 20:58
  • Ah sorry, but Joeyrp was first – Keine Ahnung Dec 01 '17 at 21:02
  • @KeineAhnung **I do not want you to accept my answer**. JoeyRp has the right answer too. I just want you to understand what both of us are trying to say. Neither of us want you to create a custom class, we both want you to use the struct and a for loop. – maccettura Dec 01 '17 at 21:03
  • 1
    @macceturra I understand it now. Sorry! – Keine Ahnung Dec 01 '17 at 21:07
  • @KeineAhnung It's ok, I just wanted to make sure you understood! I'm here to help – maccettura Dec 01 '17 at 21:21