Fai una variabile essere richiesto - di eludere NullReferenceException?
-
21-09-2019 - |
Domanda
[risolto] - L'errore è stato mio, che non mi collego mondiale (world_) per l'entità, così che era nullo. Grazie per la spiegazione tutti!
Come forse sapete ormai, sto facendo un motore di gioco / quadro, e ho rimasto bloccato collega roba con riferimenti tra loro.
Esempio:
public void Attach(Entity Entity)
{
entity_ = Entity;
entity_.world_.renderer_.AddComponent(this);
}
La linea che aggiunge componente al renderer viene a mancare con NullObjectException. La mia idea era che è perché è dentro l'implementazione della classe (quando l'oggetto non è ancora definita), ma tale cosa ha funzionato nel prossimo pezzo di codice:
public TGSGame()
{
...
Renderer = new RenderManager(this);
...
}
La parte di codice è all'interno implementazione della classe TGSGame troppo!
Qualcuno ha idea di come posso superare questa eccezione?
Soluzione
È necessario verificare entity_
, entity_.world_
e entity_.world_.renderer_
- se qualsiasi di questi sono null
esploderà. Se questi sono fondamentali per l'oggetto, di solito è una buona idea per inizializzare loro nel costruttore, e limitano se possono essere modificati / impostati ritorna nullo. Ad esempio:
public class Entity {
public World World {get;private set;}
public Entity(World world) {
if(world == null) throw new ArgumentNullException("world");
tihs.World = world;
}
}
Il vantaggio di questo è che è molto evidente dove il problema è (si mostrerà come un ArgumentNullException
, dell'argomento "world"
, con lo stack-trace indicando il costruttore World
e quant'altro sia chiamandolo, etc)
Altri suggerimenti
Bene, la linea incriminata è
entity_.world_.renderer_.AddComponent(this);
quindi o
entity_.world_
è null
o
entity_.world_.renderer_
è null
o qualcosa di brutto sta accadendo all'interno di
entity_.world_.renderer_.AddComponent
Una traccia dello stack ci aiuterebbe a dedurre un po 'di più, ma quelli sono i tuoi colpevoli. Inizia controllando se entity_.world_
viene inizializzato correttamente e in caso affermativo, se entity_world_.renderer_
viene inizializzato correttamente.
Uno dei riferimenti nella catena di entity_.world_.renderer_
è nullo, il che non è sorprendente, dal momento che avete appena creato nella riga precedente. Si noti che avere un oggetto in sé aggiungere quel modo per una raccolta esterna è un'inversione di responsabilità bizzarro -. Di solito chi sta controllando la raccolta dovrebbe ottenere il controllo su chi aggiunge le cose ad esso
Direi o membri world_
o di riferimento renderer_
che non sono ancora stato inizializzato. Uno che o entity_
viene passato come un null
. E 'un po' difficile da dire, senza ulteriori informazioni su ciò che essi sono però.
È necessario assicurarsi che "world_" e "renderer_" esistono sia prima della chiamata da allegare.
È possibile utilizzare il codice difensiva:
if ((entity_ != null) && (entity_.world_ != null) && (renderer_ != null)) {
//... your code here...
} else {
throw new Exception("...");
}
Oltre a ciò, è necessario guardare a come si costruisce il grafico oggetto per garantire che questa situazione non si verifica. Una buona combinazione di fabbrica e Singleton modello può aiutare in questo caso.
Forse avete avuto NullReferenceException? In ogni caso, vorrei ricontrollare che né
entity_.world_
né
entity_.world_.renderer_
Non è nullo. Basta posizionare un punto di interruzione e vedrete che il vostro argomento Entità non è completamente inizializzato.