开发者

Make a variable be required - to evade NullReferenceException?

开发者 https://www.devze.com 2022-12-17 16:46 出处:网络
[SOLVED] - The mistake was mine, that I didn\'t link World (world_) to the entity, so that was null. Thanks for the explanation everyone!

[SOLVED] - The mistake was mine, that I didn't link World (world_) to the entity, so that was null. Thanks for the explanation everyone!


As you may know by now, I'm making a game engine/framework, and I've got stuck linking stuff with references to each other.

Example:

public void Attach(Entity Entity)
{
    entity_ = Entity;
   开发者_如何学Python entity_.world_.renderer_.AddComponent(this);
}

The line that adds component to the renderer fails with NullObjectException. My idea was that it's because it's inside the class implementation (when the object isn't defined yet), but such thing worked in next piece of code:

public TGSGame()
{
    ...
    Renderer = new RenderManager(this);
    ...
}

That part of code is inside TGSGame class implementation too!

Does anyone have idea how can I overcome this exception?


You need to check entity_, entity_.world_ and entity_.world_.renderer_ - if any of these are null it will explode. If these are fundamental to the object, it is usually a good idea to initialize them in the constructor, and limit whether they can be changed / set back to null. For example:

public class Entity {
    public World World {get;private set;}
    public Entity(World world) {
        if(world == null) throw new ArgumentNullException("world");
        tihs.World = world;
    }
}

The advantage of this is that it is very obvious where the problem is (it will show as an ArgumentNullException, of the "world" argument, with the stack-trace pointing at the World constructor and whatever is calling it, etc)


Well, the offending line is

entity_.world_.renderer_.AddComponent(this);

so either

entity_.world_

is null or

entity_.world_.renderer_

is null or something bad is happening inside of

entity_.world_.renderer_.AddComponent

A stack trace would help us deduce a little more but those are your culprits. Start by checking if entity_.world_ is being initialized properly and if so if entity_world_.renderer_ is being initialized properly.


One of the references in the chain of entity_.world_.renderer_ is null, which isn't surprising, since you just created it in the previous line. Note that having an object add itself that way to an external collection is a bizarre responsibility inversion -- usually whoever is controlling the collection should get control over who adds things to it.


I'd guess either world_ or renderer_ reference members which have not yet been initialised. Either that or entity_ is passed in as a null. It's a bit hard to tell without more info on what they are though.


You need to ensure that "world_" and "renderer_" both exist before the call to Attach.

You could use defensive code:

if ((entity_ != null) && (entity_.world_ != null) && (renderer_ != null)) {
   //... your code here...
} else {
   throw new Exception("...");
}

Beyond that, you need to look at how you build your object graph to ensure that this situation does not arise. A good combination of Factory and Singleton pattern can help in this case.


Perhaps you had NullReferenceException? Anyway, I would double-check that neither

entity_.world_

nor

entity_.world_.renderer_

is not null. Just place a breakpoint and you'll see that your Entity argument isn't completely initialized.

0

精彩评论

暂无评论...
验证码 换一张
取 消