-1

Here's what I used to solve this problem:

public class Snake {
List<Rectangle> bodyParts = new List<Rectangle>();
}

Snake snk = new Snake();
snk.bodyParts.Add(new Rectangle(760,25,8,8))

//the Exception Occurs here
//snk.bodyParts[0].Y = snk.bodyPArts[0].Y-10;

//Here's my approach
snk.bodyParts[0] = new Rectangle(bodyParts[0].X,bodyParts[0].Y-10,8,8);

Exception: Cannot modify the return value of 'System.Collections.Generic.List.this[int]'

My question is: Are they any alternative/better ways to manage this exception ?

Thanks.

EDIT: I got my answer, can you please close this question.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
RandomBeginner
  • 472
  • 2
  • 8
  • 17
  • What exception? – Blorgbeard Nov 28 '17 at 19:36
  • You should think of adding your stack trace and a bigger code sample of your issue ! – Kevin Avignon Nov 28 '17 at 19:38
  • Oh, I'm sorry(First time posting). I thought it was clear, I'll edit my question right away. – RandomBeginner Nov 28 '17 at 19:40
  • 1
    https://stackoverflow.com/questions/414981/directly-modifying-listt-elements. TDLR: don't use a struct. – Dylan Nicholson Nov 28 '17 at 20:04
  • I'm sorry I've already read that post, but I'm not sure what do you mean by not using a struct, as I didn't use it? – RandomBeginner Nov 28 '17 at 20:12
  • **Moderator Note**: Please do not vandalize your posts. Once you post a question, they belong to the site and its users. Even if it is no longer useful to you, it might be helpful to someone in the future. The answerers would have also put an effort in writing their answer, which would no longer be useful if you have removed the content from the post. Also, note that by posting on the Stack Exchange network, you've granted a non-revocable right for SE to distribute that content (under the CC BY-SA 3.0 license). By SE policy, any vandalism will be reverted. – Bhargav Rao May 22 '18 at 22:46

3 Answers3

1

Rather than working directly with Rectangles, how about adding a BodyPart class, with some manipulation methods:

public class BodyPart
{
    private Rectangle rectangle;

    public BodyPart(Rectangle rectangle)
    {
        this.rectangle = rectangle;
    }

    public void MoveY(int value)
    {
        rectangle.Y += value;
    }

    public void MoveX(int value)
    {
        rectangle.X += value;
    }
}

public class Snake
{
    public List<BodyPart> Parts = new List<BodyPart>();
}

public class AppSnake
{
    public void Run()
    {
        var snake = new Snake();
        snake.Parts.Add(new BodyPart(new Rectangle(760, 25, 8, 8)));
        snake.Parts[0].MoveY(-10);
    }
}
Aron
  • 3,877
  • 3
  • 14
  • 21
0

Rectangle, RectangleF, Point, PointF, Size and SizeF are value types (struct type). This means that you can not/should not change an individual part of the structure.

The reason is that unlike classes each variable keeps its own copy of the structure. When you type list[0].X = 10, the indexer list[0] returns a copy of the rectangle and not the original value. The correct way is to assign a new rectangle list[0] = A which copies all the values from A into the array.

Please read more on value types and structs before attempting to write code that uses them.

The quickest way to fix your code without completely changing it around is by adding methods that manipulate all the body parts in predefined ways:

public class Snake
{
    public List<Rectangle> Parts { get; } = new List<Rectangle>();

    public void MoveX(int delta)
    {
        for(int i = 0; i < Parts.Count; i++)
        {
            // Read the current rectangle from the list
            var rect = Parts[i];
            // Change the coordinate.
            rect.X += delta;
            // Write the modified rectangle back into the list
            Parts[i] = rect;
        }
    }
    public void MoveY(int delta)
    {
        for(int i = 0; i < Parts.Count; i++)
        {
            // Read the current rectangle from the list
            var rect = Parts[i];
            // Change the coordinate.
            rect.Y += delta;
            // Write the modified rectangle back into the list
            Parts[i] = rect;
        }
    }
}
John Alexiou
  • 28,472
  • 11
  • 77
  • 133
  • 1
    Thank you so much, although I'm aware of structs in C#, it didn't occur to me that these objects are structs. But everything is clear now. – RandomBeginner Nov 28 '17 at 21:21
-1

Use Rectangle.Location and Rectanagle.Size properties e.g.:

snk.bodyParts[0].Location = new Point(newX, newY);
snk.bodyParts[0].Size = new Size(newWidth, newHeight);