我必须在这种自定义对象中实现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方法不会处理任何东西,所以我应该执行它吗?
正确的做法是什么?
说你和我是好朋友,有一天你来找我借我的割草机。我当然同意;毕竟你是我的朋友,我希望你能适当地尊重我的财产。
几天后,我需要修剪草坪,所以我来你家要求你归还我的割草机。"对不起,"你说,"我不能。"
"为什么不呢?"我问。
"嗯,我把它拿出来,放在棚子后面,放火烧了。"
这是你在第一个例子中提出的建议。您正在加载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()
。