如何在C#中实现数组索引器

时间:2022-09-02 00:17:22

I can type

我可以打字

Square[,,,] squares = new Square[3, 2, 5, 5];
squares[0, 0, 0, 1] = new Square();

In fact, I expect I could keep going adding dimensions to Int.MaxValue though I have no idea how much memory that would require.

事实上,我希望我可以继续向Int.MaxValue添加维度,虽然我不知道需要多少内存。

How could I implement this variable indexing feature in my own class? I want to encapsulate a multi dimensional array of unknown dimensions and make it available as a property thus enabling indexing in this manner. Must I always know the size in which case how does Array work?

我怎么能在我自己的类中实现这个变量索引功能?我想封装一个未知维度的多维数组,并使其可用作属性,从而以这种方式启用索引。我必须始终知道大小在哪种情况下Array如何工作?

EDIT

Thanks for the comments, here is what I ended up with - I did think of params but didn't know where to go after that not knowing about GetValue.

感谢您的评论,这就是我最终的结果 - 我确实想到了params,但在不了解GetValue之后不知道该去哪里。

class ArrayExt<T>
{
  public Array Array { get; set; }

  public T this[params int[] indices] 
  {
      get { return (T)Array.GetValue(indices); }
      set { Array.SetValue(value, indices);}
  }
}

ArrayExt<Square> ext = new ArrayExt<Square>();
ext.Array = new Square[4, 5, 5, 5];
ext[3, 3, 3, 3] = new Square();

TBH I don't really need this now. I was just looking for a way to extend Array to initialize its elements having resolved to avoid for loop initialization code outside the class whenever I was using a multi array (mainly in unit tests). Then I hit intellisense and saw the Initialize method...though it restricts me to a default constructor and value types. For reference types an extension method would be required. Still I learnt something and yes, there was a runtime error when I tried an array with more than 32 dimensions.

TBH我现在不需要这个。我只是在寻找一种方法来扩展Array来初始化它已解析的元素,以避免在我使用多数组(主要是在单元测试中)时类外的循环初始化代码。然后我点击intellisense并看到了Initialize方法......虽然它将我限制为默认构造函数和值类型。对于参考类型,将需要扩展方法。我仍然学到了一些东西,是的,当我尝试一个超过32维的数组时,出现了运行时错误。

3 个解决方案

#1


6  

You could use varargs:

你可以使用varargs:

class Squares {
    public Square this[params int[] indices] {
        get {
            // ...
        }
    }
}

You'd have to handle the fact indices can have an arbitrary length yourself, in whicheevr way you feel is appropriate. (E.g. check the size of indices against the array rank, type it as Array and use GetValue().)

你必须处理事实索引你自己可以有任意长度,你认为合适的方式。 (例如,检查数组排名的索引大小,将其键入Array并使用GetValue()。)

#2


7  

Arrays types are magic – int[] and int[,] are two different types, with separate indexers.
These types are not defined in source code; rather, their existence and behavior are described by the spec.

数组类型是魔术 - int []和int [,]是两种不同的类型,具有单独的索引器。这些类型未在源代码中定义;相反,它们的存在和行为由规范描述。

You would need to create a separate type for each dimensionality – a Matrix1 class with a this[int], a Matrix2 class with a this[int, int], and so on.

您需要为每个维度创建一个单独的类型 - 一个带有this [int]的Matrix1类,一个带有this [int,int]的Matrix2类,依此类推。

#3


1  

use the this[] operator:

使用this []运算符:

public int this[int i, int j]
{
    get {return 1;}
    set { ; }
}

Note that you can't have a variable number of dimensions in one operator - you have to code each method separately:

请注意,在一个运算符中不能包含可变数量的维度 - 您必须分别对每个方法进行编码:

public int this[int i, int j, int k]
{
    get {return 1;}
    set { ; }
}
public int this[int i, int j]
{
    get {return 1;}
    set { ; }
}
public int this[int i]
{
    get {return 1;}
    set { ; }
}

I expect I could keep going adding dimensions to Int.MaxValue

我希望我可以继续向Int.MaxValue添加维度

You'd be wrong:

你错了:

An array can have a maximum of 32 dimensions.

一个数组最多可以有32个维度。

#1


6  

You could use varargs:

你可以使用varargs:

class Squares {
    public Square this[params int[] indices] {
        get {
            // ...
        }
    }
}

You'd have to handle the fact indices can have an arbitrary length yourself, in whicheevr way you feel is appropriate. (E.g. check the size of indices against the array rank, type it as Array and use GetValue().)

你必须处理事实索引你自己可以有任意长度,你认为合适的方式。 (例如,检查数组排名的索引大小,将其键入Array并使用GetValue()。)

#2


7  

Arrays types are magic – int[] and int[,] are two different types, with separate indexers.
These types are not defined in source code; rather, their existence and behavior are described by the spec.

数组类型是魔术 - int []和int [,]是两种不同的类型,具有单独的索引器。这些类型未在源代码中定义;相反,它们的存在和行为由规范描述。

You would need to create a separate type for each dimensionality – a Matrix1 class with a this[int], a Matrix2 class with a this[int, int], and so on.

您需要为每个维度创建一个单独的类型 - 一个带有this [int]的Matrix1类,一个带有this [int,int]的Matrix2类,依此类推。

#3


1  

use the this[] operator:

使用this []运算符:

public int this[int i, int j]
{
    get {return 1;}
    set { ; }
}

Note that you can't have a variable number of dimensions in one operator - you have to code each method separately:

请注意,在一个运算符中不能包含可变数量的维度 - 您必须分别对每个方法进行编码:

public int this[int i, int j, int k]
{
    get {return 1;}
    set { ; }
}
public int this[int i, int j]
{
    get {return 1;}
    set { ; }
}
public int this[int i]
{
    get {return 1;}
    set { ; }
}

I expect I could keep going adding dimensions to Int.MaxValue

我希望我可以继续向Int.MaxValue添加维度

You'd be wrong:

你错了:

An array can have a maximum of 32 dimensions.

一个数组最多可以有32个维度。