Search code examples
c#propertiesunity-game-engineindicesindexer

In C# is it possible to have an custom Indexer property of a type that is NOT a string or an int?


In C# is it possible to have an Indexer property of a type that is not a string or an int?

For example I have a custom object that is a map of 2D vector coordinates. Taking the basics of my map class to be...

public class TileMap
{
    /// <summary>
    /// The holds an array of tiles
    /// </summary>
    MapTile[,] _map;

    /// <summary>
    /// Gets the <see cref="PathFindingMapTile"/> with the specified position.
    /// </summary>
    /// <value>
    /// The <see cref="PathFindingMapTile"/>.
    /// </value>
    /// <param name="position">The position.</param>
    /// <returns></returns>
    public MapTile this[Vector2 position]   // Indexer declaration
    {
        get
        { 
            int x = (int)position.x;
            int y = (int)position.y;
            return _map[x, y]; 
        }
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="TileMap"/> class.
    /// </summary>
    /// <param name="length">The length.</param>
    /// <param name="height">The height.</param>
    public TileMap(int length, int height)
    {
        _map = new MapTile[length, height];
    }

}

This compiles without issue. However the calling code fails with two errors

Base class

internal abstract class MyBase
{
    /// <summary>
    /// Gets (or privately sets) the tile map
    /// </summary>
    protected PathFindingMapTile[,] TileMap { get; private set; }
}

derived class

internal class MyDerived : MyBase
{
    public void MyMethod()
    {
        Vector2 possiblePosition;
        MapTile possibleTile = null;

        possibleTile = this.TileMap[possiblePosition]; // <-- This line wont compile
    }
}

Compile Errors:

Cannot implicitly convert type 'UnityEngine.Vector2' to 'int' 
Wrong number of indices inside []; expected 2

Why two indices? I have stated just one, the position. Any suggestions?

Update - Following Rufus comment. Corrected return type of "Tilemap" property of the base class.

internal abstract class MyBase
{
    /// <summary>
    /// Gets (or privately sets) the tile map
    /// </summary>
    protected TileMap TileMap { get; private set; }
}

Solution

  • The problem is that your TileMap property is not of type TileMap, it's of type PathFindingMapTile[,], which requires two indexes.