Hi. I'm making a space game and I need the spaceship to shoot bullets. So in order to make this happen I need a collection which can allow the following:

1.Adding an object (so that we can shoot new bullets)
2.Looping through and modifying all the objects (so that we can change the positions of the bullets)
3.Removing an object that meets a certain condition (so that we can remove all bullets which have left the game limits)

At first I thought of using a List<> but the problem with it is that it doesn't allow looping through and modifying the objects (#2) since you can't assign to an iteration variable when using a foreach loop.
Using a regular array doesn't solve the problem either because it's hell trying to remove only certain objects from it (#3), although it is possible (but very ineffective and troublesome).

So is there a collection that can do all the three things I mentioned or if there isn't what is the easiest way to implement such thing?

Hi

I think you can use List<> collection then avoid using a foreach since its read only. you can use a for loop to loop through it all. plus the nice thing about using those collections from the Generics namespace is that you can perform linq queries on them making it simple for you to choose certain objects depending on their criteria.

As of about modifying objects from the collection you can you use methods like Remove(T obj), Insert(T obj, int index), Add(T obj) etc to make changes on your collection plus its a bonus that you don't have to cast anything from object your type.

I'm bad at explaining things so please tell me if you don't understand

You can modify the values in an object that is part of a list, so I don't understand your #2 problem. You can't assign a new object to that location, as IEnumerable doesn't allow changing the list as you move through it (which is your #3 problem). To solve this you can build a list of processed objects as you move through it and reassign the new list when you get done:

List<Bullets> newList = new List<Bullets>();
foreach (Bullet b in myBullets) {
    // do whatever processing
    if (b is still a good bullet) {
        newList.Add(b);
    }
}
myBullets = newList;

Hopefully it is obvious to you that this is not compilable code, just something to give you an idea :)

Hi

I think you can use List<> collection then avoid using a foreach since its read only. you can use a for loop to loop through it all. plus the nice thing about using those collections from the Generics namespace is that you can perform linq queries on them making it simple for you to choose certain objects depending on their criteria.

As of about modifying objects from the collection you can you use methods like Remove(T obj), Insert(T obj, int index), Add(T obj) etc to make changes on your collection plus its a bonus that you don't have to cast anything from object your type.

I'm bad at explaining things so please tell me if you don't understand

Thanks, but how would I use a for loop to loop through a List<>? I don't think you can access List<> items by index.

You can modify the values in an object that is part of a list, so I don't understand your #2 problem. You can't assign a new object to that location, as IEnumerable doesn't allow changing the list as you move through it (which is your #3 problem). To solve this you can build a list of processed objects as you move through it and reassign the new list when you get done:

List<Bullets> newList = new List<Bullets>();
foreach (Bullet b in myBullets) {
    // do whatever processing
    if (b is still a good bullet) {
        newList.Add(b);
    }
}
myBullets = newList;

Hopefully it is obvious to you that this is not compilable code, just something to give you an idea :)

How do I modify the values in an object that is part of the list? I want to modify the values of every object in the list. You can't do that with a foreach loop and I don't see another way of doing it.

Thanks, but how would I use a for loop to loop through a List<>? I don't think you can access List<> items by index.

You can access items in a List<T> by index:

static void Main() {
    List<int> list = new List<int>();
    list.Add(2);
    list.Add(17);
    list.Add(5);

    for (int i = 0; i < list.Count; i++) {
        Console.WriteLine("Index {0} has a value of {1}", i, list[i]);
    }
           
    Console.ReadLine();
}

Edited 6 Years Ago by Momerath: n/a

How do I modify the values in an object that is part of the list? I want to modify the values of every object in the list. You can't do that with a foreach loop and I don't see another way of doing it.

You can do it with a foreach loop, I'm not sure why you think you can't:

using System;
using System.Collections.Generic;

namespace TestApp {
    class View {
        static void Main() {
            List<Point> list = new List<Point>();

            for (int i = 0; i < 3; i++) {
                list.Add(new Point(i + 1, (i + 1) * 2));
            }

            Console.WriteLine("Before change loop");
            foreach (Point p in list) {
                Console.WriteLine("The point has values of ({0}, {1})", p.X, p.Y);
            }
            Console.WriteLine();

            foreach (Point p in list) {
                p.X = p.X + 1;
            }

            Console.WriteLine("After change loop");
            foreach (Point p in list) {
                Console.WriteLine("The point has values of ({0}, {1})", p.X, p.Y);
            }
           
            Console.ReadLine();
        }
    }

    class Point {
        public int X { get; set; }
        public int Y { get; set; }

        public Point(int x, int y) {
            X = x;
            Y = y;
        }
    }
}

Gives an output of:

Before change loop
The point has values of (1, 2)
The point has values of (2, 4)
The point has values of (3, 6)

After change loop
The point has values of (2, 2)
The point has values of (3, 4)
The point has values of (4, 6)

You can do it with a foreach loop, I'm not sure why you think you can't:

using System;
using System.Collections.Generic;

namespace TestApp {
    class View {
        static void Main() {
            List<Point> list = new List<Point>();

            for (int i = 0; i < 3; i++) {
                list.Add(new Point(i + 1, (i + 1) * 2));
            }

            Console.WriteLine("Before change loop");
            foreach (Point p in list) {
                Console.WriteLine("The point has values of ({0}, {1})", p.X, p.Y);
            }
            Console.WriteLine();

            foreach (Point p in list) {
                p.X = p.X + 1;
            }

            Console.WriteLine("After change loop");
            foreach (Point p in list) {
                Console.WriteLine("The point has values of ({0}, {1})", p.X, p.Y);
            }
           
            Console.ReadLine();
        }
    }

    class Point {
        public int X { get; set; }
        public int Y { get; set; }

        public Point(int x, int y) {
            X = x;
            Y = y;
        }
    }
}

Gives an output of:

Before change loop
The point has values of (1, 2)
The point has values of (2, 4)
The point has values of (3, 6)

After change loop
The point has values of (2, 2)
The point has values of (3, 4)
The point has values of (4, 6)

For some reason this doesn't work on managed classes (try doing a foreach loop on a list that contains strings) and results in the following compiler error: http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k%28CS1656%29;k%28TargetFrameworkMoniker-%22.NETFRAMEWORK%2cVERSION%3dV3.5%22%29&rd=true

Never mind, I've managed to get this done with a for loop. Thanks.

Edited 6 Years Ago by moni94: n/a

This question has already been answered. Start a new discussion instead.