使用结构作为多维数组索引

本文关键字:数组 索引 结构 | 更新日期: 2023-09-27 18:24:30

我有一个3D阵列,我正在以这种方式访问Array(int x, int y, int z)。我想知道的是,如果有可能有一个结构,其中有xyz,这样我就可以这样使用它:Array(struct xyz).如果是,那么如何使用?

我之所以想要这个,是因为它对我来说读写更容易,而且写起来更简单,也不容易出错。更容易维护大局。

我知道我可以创建一个有自己方法的类,但由于我有很多类,并且将其应用于每一个类会使我很快失去可读性,因此如果可用,直接使用结构将是更好的选择。

示例:

public struct xyz
{
    public int x, y, z;
    public xyz(int X, int Y, int Z)
    {
        x = X;
        y = Y;
        z = Z;
    }
}
private void Test()
{
    int(,,) Array = new int()
    {
        {
            {0,0},
            {0,0},
        },
        {
            {0,0},
            {0,0},
        }
    };
    xyz XYZ = new xyz(0,0,0);
    Array[XYZ] = 1; // this instead of
    Array[XYZ.x, XYZ.y, XYZ.z] = 1 // this
}

使用结构作为多维数组索引

您可以创建自己的数组类来包装真实数组,并提供索引器来执行您想要的操作:

class MyArray<T>
{
    private T[,,] array;
    public MyArray(int xSize, int ySize, int zSize)
    {
        array = new T[xSize,ySize,zSize];
    }
    public T this[XYZ xyz]
    {
        get { return array[xyz.x, xyz.y, xyz.z]; }
        set { array[xyz.x, xyz.y, xyz.z] = value; }
    }
}

您可以通过创建自己的集合轻松实现这一点,该集合可以通过单独指定所有坐标来访问:

public T this[int x, int y, int z] { get { … } set { … } }

或者通过您的XYZ结构:

public T this[XYZ xyz]  { get { … } set { … } }

不能将该索引器添加到数组中,扩展索引器是不可能的。您可以创建两个扩展方法。类似于:

public static T Get<T>(this T[,,] array, XYZ xyz)
{
    return array[xyz.X, xyz.Y, xyz.Z];
}
public static void Set<T>(this T[,,] array, XYZ xyz, T value)
{
    array[xyz.X, xyz.Y, xyz.Z] = value;
}

然后像这样使用:

int i = array.Get(xyz);
array.Set(xyz, 25);

此外,像您所做的那样创建可变的struct被认为是C#中最糟糕的做法。它们可能非常令人困惑。

完成@Andrew Cooper的解决方案,如果您也想正常访问该矩阵,则必须添加以下方法(查看Andrew代码的末尾)

class MyArray<T>
{
    private T[,,] array;
    // Constructor
    public MyArray(int xSize, int ySize, int zSize)
    {
        array = new T[xSize,ySize,zSize];
    }
    // Index with your own struct XYZ
    public T this[XYZ xyz]
    {
        get { return array[xyz.x, xyz.y, xyz.z]; }
        set { array[xyz.x, xyz.y, xyz.z] = value; }
    }
    // Normal index
    public T this[int x, int y , int z]
    {
        get { return array[x, y, z]; }
        set { array[x, y, z] = value; }
    }
    // Get dimensions
    public int GetLength(int dim)
    {
        return array.GetLength(dim);
    }
}