我必须在这种自定义对象中实现Dispose方法吗?

本文关键字:实现 Dispose 方法 对象 自定义 | 更新日期: 2023-09-27 18:06:25

第一个例子

public class GameObject
{
    Vector2 position;
    Vector2 scale;
    Color color;
    Texture2D atlas_reference;
    Rectangle source_rectangle;
    public GameObject()
    {
        //...
        // atlas_reference is a reference to the texture loaded in "LoadContent" in the main XNA's
        // loop
    }
    // ...
    // ...
    // ...
    public void Update(GameTime dt)
    { 
        //...
    }
    public void Draw(SpriteBatch spritebatch)
    { 
        //...
    }
}

我应该实现Dispose方法吗?

public void Dispose()
{
    atlas_reference.Dispose(); // ?
}

我认为没有,因为我将把方法放在加载它的地方。在这个类中,它只获得一个引用。我错了吗?也许我只需要做:atlas_reference = null; ?

第二个例子
public class GameWorld
{
    List<GameObject> game_objects;
    const int obj_number = 1000;
    public GameWorld()
    {
        //...
        for (int i = 0; i < 1000; ++i)
            game_objects[i] = new GameObject(); 
        // ...
    }
    // ...
    // ...
    // ...
    public void Update(GameTime dt)
    { 
        //... loop through the list and update every one
    }
    public void Draw(SpriteBatch spritebatch)
    { 
        //... loop through the list and draw every one
    }
}

这里我认为我应该实现Dispose因为我正在生成一些对象,所以:

public void Dispose()
{
    for (int i = obj_number; i >= 0; --i)
        game_objects[i].Dispose();
}

但是我知道GameObject的dispose方法不会处理任何东西,所以我应该执行它吗?

正确的做法是什么?

我必须在这种自定义对象中实现Dispose方法吗?

说你和我是好朋友,有一天你来找我借我的割草机。我当然同意;毕竟你是我的朋友,我希望你能适当地尊重我的财产。

几天后,我需要修剪草坪,所以我来你家要求你归还我的割草机。"对不起,"你说,"我不能。"

"为什么不呢?"我问。

"嗯,我把它拿出来,放在棚子后面,放火烧了。"

这是你在第一个例子中提出的建议。您正在加载asset_reference在您的Game对象,大概是通过它的内容管理器。在XNA中,内容管理器拥有它加载的资产。它将它们存储在内部缓存中,这样就不必在每次请求时重新加载它们。所以如果你这样做:

var resource = content.Load<Foo>("bar").Baz();
resource.Dispose();
content.Load<Foo>("bar").Baz();

第二次调用Baz()几乎肯定会抛出ObjectDisposedException !你想用你的疯邻居留下的烧坏的割草机割草。

对象应该管理其拥有的资源的生命周期。就像你没有权利烧毁我的割草机一样,另一个类也没有权利烧毁给它的资源,除非你明确地转让资源的所有权。

第二个例子更接近我认为合适的——一个对象正在处理它创建并因此拥有的资源——但是如果你知道GameObject上的Dispose()方法没有做任何事情,那么为什么它要实现IDisposable呢?

根据MSDN,您只需要实现IDisposable来释放未管理的资源。XNA负责内容管道,所以你不需要担心你的Texture2D。

对象持有的引用将在销毁时被取消,因此您也不需要担心这个问题。c#使用引用计数的垃圾收集器,因此一旦计数达到0,它将自动被收集。

直接引用:

只有当你的类型直接使用非托管资源时,你才应该实现IDisposable。

据我所知,如果你的类包含IDisposable的成员,你也应该让你的类实现IDisposable,并在你的类Dispose()方法中的所有一次性成员上调用Dispose()