如何使用 C# 分配带有索引器属性的自定义 class?

How to assign a custom class with indexer attribute with C#?

我有一个名为 Matrix 的自定义 class,我应用了一个 indexer,因此它接受作为多维数组的赋值和读取值。 Matrix class 构造函数接受 rowscolumns 作为本机数组的矩阵参数。

当我尝试赋值时,出现以下异常:

Stack overflow. Repeat 24101 times: at Matrix.set_Item(Int32, Int32, Int32)

下面列出了我的 Matrix class 的最终代码。

矩阵class

class Matrix
{
  //declare the variable to hold the number of columns
  private int cols;

  //declare the variable to hold the number of rows
  private int rows;

  //define the constructor to accept the above arguments from a user and assign
  public Matrix(int rows, int cols)
  {
    this.rows=rows;
    this.cols=cols;
  }

  //apply indexing structure to this class to make it accept array operations(multidimensional)
  public int this[int rows,int cols]
  { 
    get
    {
      return matrixA[rows,cols]; 
    }

    set
    {
      matrixA[rows,cols] = value;
    } 
}

主要

//declare the Matrix object
static Matrix matrixA;
//the lines below shows how to use the Matrix class
static void Main(string args[])
{
  Console.WriteLine("Enter the number of rows");
  int m = Int32.Parse(Console.ReadLine());

  Console.WriteLine("Enter the number of columns");
  int n = Int32.Parse(Console.ReadLine());

  matrixA = new Matrix(m, n);
 
  for (int i = 0; i < m; i++)
  {
    for (int j = 0; j < n; j++)
    {
      //i suppose the setter is invoked by this code
      matrixA[i, j] = Int32.Parse(Console.ReadLine());
    }
  }
}

您的矩阵 class 实际上没有任何地方可以 存储 任何数据;将矩阵的数据存储 inside 矩阵 class:

class Matrix
{
  private int[,] _data;

  //define the constructor to accept the above arguments from a user and assign
  public Matrix(int rows, int cols)
  {
    _data = new int[rows,cols];
  }

  //apply indexing structure to this class to make it accept array operations(multidimensional)
  public int this[int row, int col]
  { 
    get
    {
      return _data[row,col]; 
    }

    set
    {
      _data[row,col] = value;
    } 
}

我想你已经把你的 Matrix class 放在你的程序 class 中(因此 Matrix 的 setter 如何能够访问静态 matrixA 变量..) - 我会说现在,要坚持“永远不要把一个 class 放在另一个里面”的规则。 class-inside-class 执行 work/is 合法的 C# 语法,在某些情况下可能需要它,但通常(尤其是开始时)它不是;避免这样做。如果你必须这样做才能“让其他东西工作”那么它可能表明其他地方有问题

主要是:


static void Main(string[] args) //in c# we put [] after the type, not the argument name
{
  Console.WriteLine("Enter the number of rows");
  int m = Int32.Parse(Console.ReadLine());

  Console.WriteLine("Enter the number of columns");
  int n = Int32.Parse(Console.ReadLine());

  var matrixA = new Matrix(m, n);

  ...

至于为什么都出错了:

您试图在循环(红色箭头)中访问 matrixA - 这意味着您正在访问 main 顶部的 matrixA。您正在尝试设置一个值,以便 C# 运行设置的代码。 set 做的第一件事是访问 matrixA(绿线)以执行 set,因此 C# 开始调用 set(蓝线),这意味着这一切只是在一个无休止的圈子里兜兜转转,blue/green/blue/green...

尝试使用 getter 的行为相同;您的代码实际上从未获取或存储任何数据,因为没有任何数据存储,它只是一遍又一遍地访问自己

当您将数据保存在 class 中时,这不会发生,因为 setter 最终不会访问自身;它访问数据存储。

在一个更简单的例子中:

  class Person{
     
    string name;

    void SetNameBroken(string nameToSet){
      SetNameBroken(nameToSet);
    }
 
    void SetNameWorking(string nameToSet){
      name = nameToSet;
    }
  }