首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >抽象类的析构函数

抽象类的析构函数
EN

Stack Overflow用户
提问于 2014-05-09 23:09:38
回答 2查看 4.1K关注 0票数 6

在C++中,我知道当您打算从基类继承时,通常应该使用虚拟析构函数。但是,对于C#,我不确定应该做什么。考虑以下代码:

代码语言:javascript
复制
public abstract class Character
{
    private string characterName;
    public int health;

    Character()
    {

    }

    ~Character(){

    }

    public virtual void SetCharacterName( string tempName )
    {
        characterName = tempName;
    }

    public virtual string GetCharacterName( )
    {
        return characterName;
    }
}

(注意:我听说Unity3Ds实现C#与标准略有不同。也许忽略一些小的格式化错误,代码似乎是功能性的.)

我的第一反应是通过将~字符()析构函数定义为:

代码语言:javascript
复制
virtual ~Character(){

}

但是这样做会导致IDE返回一个错误。

In C#,对于希望继承的抽象类使用虚拟析构函数是必要的还是被认为是标准的?或者是否有其他方法可以使用C#?生成虚拟析构函数?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-05-09 23:37:04

C#没有确定性的破坏。事实上,它本身并没有真正的析构函数:它有终结器和IDisposable

如果垃圾收集对象实例,GC就会清理东西。当应用程序域终止时,所有对象最终都会以某种方式被清除,但在应用程序域的持续时间内,可能会出现一个给定的对象。在您的情况下,您不需要做任何事情,因为您的对象没有需要清理的资源。当GC清除未引用对象时,它们将得到正确的处理。

大多数情况下,人们不需要终结器。您可能需要阅读http://msdn.microsoft.com/en-us/library/system.object.finalize.aspx的终结器,并注意

终结器执行的确切时间未定义。要确保您的类的实例具有确定性的资源释放,请实现一个Close方法或提供一个IDisposable.Dispose实现。

您可能还需要阅读了解何时在.NET类中使用终结器并注意:

为什么最后的方法是坏的? ..。 如果一个对象有终结器,它将被放置在FinalizationQueue中,并且是主题,因此需要进行一些额外的清理。一旦不再在线程上或从全局引用中引用该对象,下次垃圾收集器(GC)运行时,它将看到该对象已准备好被收集。但它还不能收集。它必须让终结器先运行。因此GC将完成收集,然后终结器将最终完成对象,然后将出现另一个GC集合。 这会对性能产生巨大影响,因为您应该记住,所有托管线程都将停止等待GC,然后GC将停止等待终结器线程。 关于终结有更多的数据,所以我鼓励您尽可能多地阅读它,以便您以最好的方式使用它。

如果您的对象需要确定性的东西,您可以实现IDisposable并显式调用Dispose()或使用using块:

代码语言:javascript
复制
using ( Character foo = CharacterFactory.CreateInstance("Jane") )
{
   // do something useful with Jane
}

当封闭的using块退出时,将保证调用foo.Dispose()。它与此代码相同(除了foo的作用域外):

代码语言:javascript
复制
Character foo = ... ;
try
{
  ...
}
finally
{
  foo.Dispose() ;
}

然而,IDisposable的重点更多地在于确保及时释放非托管资源。DBA往往会在对象超出作用域时阻塞400个用户,并在等待GC‘s的情况下,使所有的DBA变得不爽,从而使一个正在运行的查询处于运行状态。或者您的对象超出作用域,使一个独占锁定的文件处于打开状态。

票数 11
EN

Stack Overflow用户

发布于 2014-05-09 23:11:41

在C#中,对希望继承的抽象类使用虚拟析构函数是必要的还是被认为是标准的?

通常,您不会在C#中使用任何析构函数。垃圾收集器可能在任何时候(或否)调用这些数据。

当您需要确定性清理时,实现IDisposable接口,并使用using洗净 (例如,非托管资源)。

析构函数无法继承或重载.具有更多详细信息的相关堆栈溢出线程:C#中的继承和析构函数

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23575282

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档