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

时间:2014-06-03 21:10:35

标签: c# xna xna-4.0 dispose

第一个例子

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方法没有处理任何东西,所以我应该实现它吗?

正确的做法是什么?

3 个答案:

答案 0 :(得分:2)

根据MSDN,您只需实施IDisposable即可发布非托管资源。 XNA负责内容管道,因此您无需担心Texture2D。

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

直接引用它:

  

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

答案 1 :(得分:2)

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

几天后我需要修剪草坪,所以我来到你家,请你把割草机归还。 “抱歉,”你说,“我做不到。”

“为什么不呢?”我问。

“好吧,我把它从棚子后面拿出来放火了。”

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

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

Baz()的第二次调用几乎肯定会抛出ObjectDisposedException!你正试图用你疯狂的邻居留下的烧毁的割草机割草坪。

对象应该管理他们拥有的资源的生命周期。就像你没有权利用我的割草机火炬一样,另一个班级无权为提供的资源进行火炬传递,除非你明确转移了资源的所有权

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

答案 2 :(得分:1)

据我了解,如果您的班级包含IDisposable成员,您还应该让您的班级实施IDisposable并在班级Dispose()上调用Dispose() {{1}} 1}}方法。