I have a custom class called Matrix
which I have applied an indexer
so it accepts assignment and reading values to and from it as a multi-dimensional array. The Matrix
class constructor accepts the rows
and columns
as arguments for the matrix alrernative for the native array.
When I try to assign values, I get the following exception:
Stack overflow. Repeat 24101 times: at Matrix.set_Item(Int32, Int32, Int32)
The definitive code for my Matrix class is listed below.
Matrix 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;
}
}
The Main
//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());
}
}
}
CodePudding user response:
Your Matrix class doesn't actually have anywhere to store any data; put a data storage for the matrix inside the Matrix 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;
}
}
I suppose you've put your Matrix class inside your Program class (hence how Matrix's setter is able to access the static matrixA variable..) - I would say right now, to stick to a rule of "never put one class inside another". class-inside-class does work/is legal C# syntax and there are a few situations where it might be desirable but generally (and especially when beginning) it's not; avoid doing it. If you have to do it to "get something else working" then it's likely indicative of a problem elsewhere
And in the main:
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);
...
As to why it all went wrong:
You attempt to access matrixA
in the loop (red arrow) - that means you're accessing the matrixA
at the top of main. You're trying to set a value so C# runs the set code. The first thing the set
does is access matrixA
(green line) in order to perform a set
, so C# starts calls the set
(blue line) which means it all just goes round and round in an endless circle, blue/green/blue/green...
Attempting to use the get
ter would behave the same; your code never actually gets or stores any data, because there isn't any data store, it just accesses itself over and over
This doesn't happen when you keep the data inside the class because the setter doesn't end up accessing itself; it accesses the data store instead.
In a more simplistic example:
class Person{
string name;
void SetNameBroken(string nameToSet){
SetNameBroken(nameToSet);
}
void SetNameWorking(string nameToSet){
name = nameToSet;
}
}