简体   繁体   中英

How can I create a collection of references in C#

Ok I am having a cross language hiccup. In C# with it's great collections like List and I have:

a Map class with properties of:
List <byte[]> Images;
List <Tile> Tiles;

a Tile Class of:
byte[] ImageData;
int X;
int Y;

Now I want to add an image to the Map class and have the ImageData property of the Tile Classes to "reference" it. I have discovered I can't just assign it Images[0]. You can't have a reference to an object of a List.

My fix was to create a Dictionary. Is this the best way or can I somehow have a "pointer" to a collection of objects?

  • in response to comments if i have a bunch of tiles which have imagedata pointing to the first byte array in the List and then i change that image in the list and grab the image in the Tiles and they are the previous image assignemnt. So assign tiles to have the first image in the list, then change that image, I now expect the tile sot reference the new image. They don't.

FINAL REVISION - Look at gladford3x's code (I haven't mastered formatting yet). last line in Main will be
myMap.Images[0] = image2;
well when you call the myMap.Tiles[0].ImageData it will have the data from the first byte array

I think it's the right way to go

Using a named collection within Map class

public class Map 
{
    public List<byte[]> Images;
    public Dictionary<int, Tile> Tiles;//you could use an int or a string to name the item
}

so you could set image data:

Map yourMap = new Map();
yourMap.Tile[0].ImageData = yourByteArray;

is that what you're doing?

Now I want to add an image to the Map class and have the ImageData property of the Tile Classes to "reference" it

List<Map> list = new List<Map>();
list.Add(new Map());
list[0].ImageData = new byte[];

// Access the list later on, the same Map object is referenced.

It is a reference type so it will update. You can copy the list and the original reference will still update. The class holds a value type (your byte array ImageData ) however that's stored on the heap so you don't need to worry about pointer management.

I'm not sure I fully understand. I read over the question a few times and here is what I've come up with. The following seems to work fine for me. I would recommend to use this as a proof of concept and implement the appropriate interfaces such as ICollection, IEnumerator, IList or whatever will serve your needs.


EDIT:

static void Main(string[] args) 
{
    Map myMap = new Map(); 
    myMap.Images = new List<byte[]>(); 
    myMap.Tiles = new List<Tile>(); 

    byte[] image = new byte[] { 1, 2, 3 }; 
    byte[] image2 = new byte[] { 10, 20, 30 }; 
    myMap.Add(image);
    myMap.Add(image2);

    byte[] image3 = new byte[] {100,200,255};
    myMap[0]=image3;

    printallmaps(myMap);
    myMap.Tiles.ForEach(c=>printall(c));
} 


public class Map 
{
    public List<byte[]> Images  { get; set; } 
    public byte[] this[int i]
    {
        get
        {
            return Tiles[i].ImageData;
        }
        set
        {
            if(i >= this.Count)
            {
                this.Insert(i,value);
            }
            else
            {
                Tiles[i].ImageData = value;
            }
        }
    }
    public List<Tile> Tiles { get; set; }
    public int Count {get {return Tiles.Count;}}
    public void Add(byte[] image)
    {
        this[this.Count] = image;
    }
    public void Insert(int x, byte[] image)
    {
        Tile tile = new Tile();
        tile.ImageData = image;
        Tiles.Insert(x,tile);
    }
} 

public class Tile 
{ 
    public byte[] ImageData; 
    int x; 
    int y; 
} 

The issue here is that your Map manages the Images, but the Tiles use them. If I understand correctly, you don't want the Tiles to know about the Map, so you'd prefer to reference the Image directly. What you could do in this case is create a TileImage class that contains the Image data. You keep a collection of TileImage instances in your Map and pass a TileImage to each Tile. Now you have a reference which stays fixed for a given Tile. If you want to change the image for that type of tile, you now update the Image contents of the TileImage. This creates the level of indirection that you're after.


public class TileImage
{
    public byte[] ImageData;
}

public class Tile
{
    public TileImage Image;
    int x;
    int y;
}

In real code, of course, you should encapsulate with properties and ideally make things immutable where possible.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM