У меня есть класс Ячейка:
public class Cell
{
public enum cellState
{
WATER,
SCAN,
SHIPUNIT,
SHOT,
HIT
}
public Cell()
{
currentCell = cellState.WATER;
MessageBox.Show(currentCell.ToString());
}
public cellState currentCell { get; set; }
}
Я затем пытаюсь использовать его в следующем классе:
public class NietzscheBattleshipsGameModel
{
private byte MAXCOL = 10;
private byte MAXROW = 10;
public Cell[,] HomeArray;
private Cell[,] AwayArray;
public NietzscheBattleshipsGameModel()
{
HomeArray = new Cell [MAXCOL, MAXROW];
AwayArray = new Cell [MAXCOL, MAXROW];
}
public string alphaCoords(Int32 x)
{
if (x < 0 || x > 9)
{
throw new ArgumentOutOfRangeException();
}
char alphaChar = (char)('A' + x);
return alphaChar.ToString();
}
public void test()
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
// Object reference not set to an instance of an object.
MessageBox.Show(HomeArray[i,j].currentCell.ToString());
///////////////////////////////////////////////////////
}
}
}
}
Я заканчиваю со Ссылкой на объект не набор к экземпляру объекта (между/////в вышеупомянутом коде..
Я попытался создать единственный экземпляр Ячейки, и она хорошо работает.
Когда вы создаете экземпляр массива, элементы в массиве получают значение по умолчанию для этого типа. Таким образом, для
T[] array = new T[length];
это случай, когда для каждого i
с 0 <= i
array [i] = default (T)
. Таким образом, для ссылочных типов array [i]
будет null
. Вот почему вы видите NullReferenceException
. В вашем случае Cell
является ссылочным типом, поэтому, поскольку у вас есть
HomeArray = new Cell [MAXCOL, MAXROW];
, и все, что вы сделали, это установили массив ссылок на Cell
s, но вы никогда не назначали эти ссылки экземплярам Ячейка
. То есть вы сказали компилятору: «Дайте мне массив, который может содержать ссылки на Cell
s», но вы не сказали компилятору: «Дайте мне массив, который может содержать ссылки на Cell
s и назначьте каждую из этих ссылок новому экземпляру Cell
». Таким образом, компилятор установит начальное значение этих ссылок на null
. Поэтому вам необходимо инициализировать HomeArray
:
for (int i = 0; i < MAXCOL; i++) {
for (int j = 0; j < MAXROW; j++) {
HomeArray[i, j] = new Cell();
}
}
При создании экземпляра массива предметы массива получают значение по умолчанию для этого типа. Таким образом, для
T[] array = new T[length];
для каждого i
с 0 < = i < length
имеется массив [i] = по умолчанию (T)
. Таким образом, для ссылочных типов массив [i]
будет иметь значение null
. Вот почему вы видите StartReferureException
. В случае Ячейка
является ссылочным типом, поэтому, поскольку у вас есть
HomeArray = new Cell [MAXCOL, MAXROW];
и все, что вы сделали, это создали массив ссылок на Ячейку
, но вы никогда не назначали эти ссылки экземплярам Ячейки
. То есть вы сказали компилятору «дайте мне массив, который может содержать ссылки на Камеры
s», но вы не сказали компилятору «дайте мне массив, который может содержать ссылки на Камеры
s и назначить каждую из этих ссылок новому экземпляру Камер
». Таким образом, компилятор установит начальное значение этих ссылок на null
. Поэтому необходимо инициализировать StartArray
:
for (int i = 0; i < MAXCOL; i++) {
for (int j = 0; j < MAXROW; j++) {
HomeArray[i, j] = new Cell();
}
}
-121--4594608- Когда я делал это в моем классе языков программирования, мы в итоге использовали излучатели на основе шаблона посетителя . Он работал довольно хорошо - делает переназначение его на новые языки вывода довольно легко, пока ваш AST соответствует тому, что вы печатаете довольно хорошо.
-121--2162760-Необходимо инициализировать ячейки в массивах.
public NietzscheBattleshipsGameModel()
{
HomeArray = new Cell[MAXCOL, MAXROW];
AwayArray = new Cell[MAXCOL, MAXROW];
for (int i = 0; i < MAXROW; i++)
{
for (int j = 0; j < MAXCOL; j++)
{
HomeArray[i,j] = new Cell();
AwayArray[i,j] = new Cell();
}
}
}
Массивы инициализируются как пустые - ссылка Null обусловлена тем, что HomeArray [i, j]
имеет значение null, а не потому, что HomeArray [i, j] .currentCell
имеет значение NULL.
ОБНОВЛЕНИЕ: Если у вас есть оператор, в котором несколько разных вещей могут быть нулевыми, я обычно разбиваю его на несколько строк, чтобы было легче определить, что является нулевым.
Например, в вашем случае:
MessageBox.Show(HomeArray[i,j].currentCell.ToString());
Либо HomeArray [i, j]
, либо HomeArray [i, j] .currentCell
потенциально может иметь значение null и вызывать исключение NullReferenceException - невозможно определить, из какого исключения. Если вы разделите этот оператор на части:
Cell cell = HomeArray[i,j].currentCell;
MessageBox.Show(cell.ToString());
В этом случае, если HomeArray [i, j]
имеет значение null, вы получите исключение NullReferenceException в первой строке, тогда как если ячейка
имеет значение null вы получите его на второй строчке.
Вы получаете исключение, потому что вы не назначаете экземпляр Cell ни одному из слотов ваших матриц.