Ссылка на объект не набор к экземпляру объекта

У меня есть класс Ячейка:

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());
                ///////////////////////////////////////////////////////

            }
        }
    }
}

Я заканчиваю со Ссылкой на объект не набор к экземпляру объекта (между/////в вышеупомянутом коде..

Я попытался создать единственный экземпляр Ячейки, и она хорошо работает.

5
задан jason 4 February 2010 в 18:11
поделиться

4 ответа

Когда вы создаете экземпляр массива, элементы в массиве получают значение по умолчанию для этого типа. Таким образом, для

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();
    } 
}
12
ответ дан 18 December 2019 в 08:27
поделиться

При создании экземпляра массива предметы массива получают значение по умолчанию для этого типа. Таким образом, для

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();
        }
    }
}
4
ответ дан 18 December 2019 в 08:27
поделиться

Массивы инициализируются как пустые - ссылка 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 вы получите его на второй строчке.

3
ответ дан 18 December 2019 в 08:27
поделиться

Вы получаете исключение, потому что вы не назначаете экземпляр Cell ни одному из слотов ваших матриц.

0
ответ дан 18 December 2019 в 08:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: