Search code examples
c#listref

Pass `List<List<Bitmap>>` as ref


I'm making a Space Invaders game in C#, using Bitmap to store images for the invaders, bombs, etc.
What puzzles me:
I have an abstract class GameObject representing the simple elements in the game:

protected Bitmap image;
protected Rectangle bounds;
protected Rectangle movementBounds;

public GameObject(ref Bitmap image, Point position, Rectangle movementBounds)
{
    this.image = image;
    this.bounds = new Rectangle(position, new Size(image.Width, image.Height));
    this.movementBounds = movementBounds;
}

Than a ShieldSegment class representing a single square of a Shield, which has four images for various stages of damage:

private int timesHit = 0;
private IList<Bitmap> alternateImages = new List<Bitmap>();

public ShieldSegment(ref List<Bitmap> images, Point position, Rectangle movementBounds)
    : base(ref images.First(), position, movementBounds)
{
    alternateImages = images;
}

And a Shield class which represents the whole shield as a list of segments:

private IList<ShieldSegment> segments = new List<ShieldSegment>();

//fill, upper left, upper right, lower left, lower right
public Shield(ref List<List<Bitmap>> images, Point position, Size imageSize)
{
    //upper row
    Point startPosition = position;
    segments.Add(new ShieldSegment(ref images.ElementAt(1), startPosition,new Rectangle(startPosition, imageSize)));
    startPosition.X += imageSize.Width;
    segments.Add(new ShieldSegment(ref images.ElementAt(0), startPosition,new Rectangle(startPosition, imageSize)));
    startPosition.X += imageSize.Width;
    segments.Add(new ShieldSegment(ref images.ElementAt(0), startPosition, new Rectangle(startPosition, imageSize)));
    startPosition.X += imageSize.Width;
    segments.Add(new ShieldSegment(ref images.ElementAt(2), startPosition, new Rectangle(startPosition, imageSize)));
    //middle row
    startPosition = position;
    startPosition.Y += imageSize.Height;
...

I need to pass the list elements as references, since (and sorry if I'm wrong) it would be wasteful to store the images anew for each segment and shield. It works fine when passing a single reference to Bitmap, but here I get a ref or out argument must be an assignable variable.
Is there any way to do it?


Solution

  • I need to pass the list elements as references

    You're not really being clear here. The list reference is just passed, by value by default but by reference if necessary. When you access the list, you'll get a reference. However, this code:

    public ShieldSegment(ref List<Bitmap> images, Point position, 
         Rectangle movementBounds)
        : base(ref images.First(), position, movementBounds)
    {
        alternateImages = images;
    }
    

    suggests you may not understand how parameter passing works in .NET to start with:

    • You're not changing the value of the images parameter to start with, so you don't need to use ref
    • It makes no sense to use ref with an argument which is the result of a method invocation... what do you expect it to do?

    I suggest you read my article on it, as well as my article on reference types and value types, which should clarify things.