Machen Sie eine Variable erforderlich - zu entziehen Nullreferenceexception?
-
21-09-2019 - |
Frage
[gelöst] - Der Fehler, ich war, dass ich nicht World Link habe (world_) an die Einheit, die so war null. Danke für die Erklärung alle!
Wie Sie jetzt wissen, ich mache ein Spiel-Engine / Rahmen, und ich habe stecken Verknüpfung Zeug mit Referenzen zueinander stehen.
Beispiel:
public void Attach(Entity Entity)
{
entity_ = Entity;
entity_.world_.renderer_.AddComponent(this);
}
Die Linie, die an den Renderer-Komponente fügt nicht mit NullObjectException. Meine Idee war, dass es ist, weil es in der Klassenimplementierung ist (wenn das Objekt noch nicht definiert ist), aber so etwas in der nächsten Stück Code gearbeitet:
public TGSGame()
{
...
Renderer = new RenderManager(this);
...
}
Der Teil des Codes ist innerhalb TGSGame Klassenimplementierung auch!
Hat jemand Ahnung, wie kann ich diese Ausnahme überwinden?
Lösung
Sie müssen entity_
, entity_.world_
und entity_.world_.renderer_
überprüfen - wenn jede von diesen null
sind, wird es explodieren. Wenn dies auf das Objekt von grundlegender Bedeutung ist, ist es in der Regel eine gute Idee, sie im Konstruktor zu initialisieren und zu begrenzen, ob sie geändert / Set zurück zu null werden. Zum Beispiel:
public class Entity {
public World World {get;private set;}
public Entity(World world) {
if(world == null) throw new ArgumentNullException("world");
tihs.World = world;
}
}
Der Vorteil hierbei ist, dass es sehr offensichtlich ist, wo das Problem ist (es als ArgumentNullException
, das "world"
Arguments zeigen, mit der Stapel-Trace zeigt auf dem World
Konstruktor und was es fordert, etc)
Andere Tipps
Nun, die störende Zeile ist
entity_.world_.renderer_.AddComponent(this);
so entweder
entity_.world_
ist null
oder
entity_.world_.renderer_
ist null
oder etwas Schlimmes geschieht innerhalb von
entity_.world_.renderer_.AddComponent
Ein Stack-Trace würde uns helfen, ein wenig mehr ableiten, aber das sind Ihre Schuldigen. Beginnen Sie mit der Überprüfung, ob entity_.world_
richtig initialisiert wird und wenn ja, ob entity_world_.renderer_
richtig initialisiert wird.
Eine der Referenzen in der Kette des entity_.world_.renderer_
ist null, was nicht verwunderlich ist, da man es nur in der vorherige Zeile erstellt. Beachten Sie, dass mit einem Objekt hinzufügen, sich auf diese Weise an eine externe Sammlung ist eine bizarre Verantwortung Inversion -. In der Regel, wer ist die Sammlung Kontrolle sollte die Kontrolle über bekommen die dazu sagt Dinge, um es
würde ich entweder world_
oder renderer_
Referenzelemente erraten, die noch nicht initialisiert. Entweder das, oder entity_
ist als null
geben. Es ist ein bisschen schwer, ohne weitere Informationen zu erzählen, was sie sind aber.
Sie müssen diese „world_“ gewährleisten und „renderer_“ beide vorhanden sein, bevor der Anruf zu befestigen.
Sie könnten defensiven Code verwenden:
if ((entity_ != null) && (entity_.world_ != null) && (renderer_ != null)) {
//... your code here...
} else {
throw new Exception("...");
}
Darüber hinaus, müssen Sie sehen, wie Sie Ihre Objektgraphen aufbauen, um sicherzustellen, dass diese Situation nicht auf. Eine gute Kombination von Fabrik und kann Singleton Muster in diesem Fall helfen.
Vielleicht haben Sie Nullreferenceexception? Wie auch immer, würde ich überprüfen, ob wirklich weder
entity_.world_
oder
entity_.world_.renderer_
ist nicht null. Legen Sie einfach einen Haltepunkt, und Sie werden sehen, dass Ihr Entity Argument nicht vollständig initialisiert wird.