Referência de objeto não definida para uma instância de um objeto
-
18-09-2019 - |
Pergunta
Eu tenho uma célula de classe:
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; }
}
Eu então tento usá -lo na aula seguinte:
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());
///////////////////////////////////////////////////////
}
}
}
}
Acabei com a referência do objeto não definida como uma instância de um objeto (entre o ///// no código acima ..
Eu tentei criar uma única instância de célula e funciona bem.
Solução
Quando você instancia uma matriz, os itens da matriz recebem o valor padrão para esse tipo. Assim para
T[] array = new T[length];
é o caso de que para cada i
com 0 <= i < length
temos array[i] = default(T)
. Assim, para tipos de referência array[i]
vai ser null
. É por isso que você está vendo o NullReferenceException
. No seu caso Cell
é um tipo de referência, então, já que você tem
HomeArray = new Cell [MAXCOL, MAXROW];
E tudo o que você fez é estabelecer uma variedade de referências a Cell
s, mas você nunca atribuiu essas referências a instâncias de Cell
. Isto é, você disse ao compilador "me dê uma matriz que pode manter referências a Cell
s "Mas você não disse ao compilador" me dê uma matriz que pode manter referências a Cell
s e atribuir cada uma dessas referências a uma nova instância de Cell
. "Assim, o compilador definirá o valor inicial dessas referências a null
. Portanto, você precisa inicializar o HomeArray
:
for (int i = 0; i < MAXCOL; i++) {
for (int j = 0; j < MAXROW; j++) {
HomeArray[i, j] = new Cell();
}
}
Outras dicas
Você precisa inicializar as células em suas matrizes.
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();
}
}
}
As matrizes são inicializadas para estar vazio - a referência nula é porque HomeArray[i,j]
é nulo, não porque HomeArray[i,j].currentCell
é nulo.
ATUALIZAR: Se você tiver uma declaração em que algumas coisas diferentes poderiam ser nulas, geralmente a divido em várias linhas para facilitar o fato de dizer o que é nulo.
Por exemplo, no seu caso:
MessageBox.Show(HomeArray[i,j].currentCell.ToString());
Qualquer HomeArray[i,j]
ou HomeArray[i,j].currentCell
Poderia ser potencialmente nulo e desencadear uma NullReferenceException - não há como dizer qual era a exceção. Se você dividir essa afirmação no entanto:
Cell cell = HomeArray[i,j].currentCell;
MessageBox.Show(cell.ToString());
Neste caso, se HomeArray[i,j]
é nulo então você recebe sua NullReferenceException na primeira linha, enquanto se se cell
é nulo você obtém na segunda linha.
Você está obtendo a exceção porque não está atribuindo uma instância de célula a nenhum dos slots de suas matrizes.