在 C# 中,类中的析构函数和 Finalize 方法有什么区别?

发布于 2024-07-25 20:50:38 字数 640 浏览 5 评论 0原文

类中的析构函数和 Finalize 方法之间有什么区别(如果有)?

我最近发现 Visual Studio 2008 认为析构函数与 Finalize 方法同义,这意味着 Visual Studio 不允许您在类中同时定义这两种方法。

例如,以下代码片段:

class TestFinalize
{
    ~TestFinalize()
    {
        Finalize();
    }

    public bool Finalize()
    {
        return true;
    }
}

在析构函数中调用 Finalize 时出现以下错误:

以下方法或属性之间的调用不明确: 'TestFinalize.~TestFinalize()' 和 'TestFinalize.Finalize()'

如果对 Finalize 的调用被注释掉,则会出现以下错误:

类型“ManagementConcepts.Service.TestFinalize”已定义一个名为的成员 使用相同的参数类型“最终确定”

What is the difference, if there is one, between a destructor and a Finalize method in a class?

I recently discovered that Visual Studio 2008 considers a destructor synonymous with a Finalize method, meaning that Visual Studio won't let you simultaneously define both methods in a class.

For example, the following code fragment:

class TestFinalize
{
    ~TestFinalize()
    {
        Finalize();
    }

    public bool Finalize()
    {
        return true;
    }
}

Gives the following error on the call to Finalize in the destructor:

The call is ambiguous between the following methods or properties:
'TestFinalize.~TestFinalize()' and 'TestFinalize.Finalize()'

And if the call to Finalize is commented out, it gives the following error:

Type 'ManagementConcepts.Service.TestFinalize' already defines a member called
'Finalize' with the same parameter types

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

无声无音无过去 2024-08-01 20:50:38

C# 中的析构函数会重写 System.Object.Finalize 方法。 您必须使用析构函数语法来执行此操作。 手动覆盖 Finalize 将会给您一条错误消息。

基本上,您尝试使用 Finalize 方法声明执行的操作是 隐藏基类的方法。 它将导致编译器发出警告,可以使用 new 修饰符将其静音(如果它可以工作)。 这里需要注意的重要一点是,您不能同时覆盖并声明具有相同名称的成员,因此同时拥有析构函数和 Finalize 方法将导致错误(但是您可以声明一个 public new void Finalize() 方法,尽管不建议这样做如果您没有声明析构函数)。

A destructor in C# overrides System.Object.Finalize method. You have to use destructor syntax to do so. Manually overriding Finalize will give you an error message.

Basically what you are trying to do with your Finalize method declaration is hiding the method of the base class. It will cause the compiler to issue a warning which can be silenced using the new modifier (if it was going to work). The important thing to note here is that you can't both override and declare a new member with identical name at the same time so having both a destructor and a Finalize method will result in an error (but you can, although not recommended, declare a public new void Finalize() method if you're not declaring a destructor).

寒江雪… 2024-08-01 20:50:38

维基百科对终结器和析构函数之间的区别有一些很好的讨论。 href="http://en.wikipedia.org/wiki/Finalizer" rel="noreferrer">终结器文章。

C# 确实没有“真正的”析构函数。 语法类似于 C++ 析构函数,但它实际上是终结器。 您在示例的第一部分中正确地编写了它:

~ClassName() { }

上面是 Finalize 函数的语法糖。 它确保基础中的终结器能够运行,但在其他方面与覆盖 Finalize 函数相同。 这意味着当您编写析构函数语法时,您实际上是在编写终结器。

根据 Microsoft 的说法,终结器是指垃圾收集器调用的函数当它收集时 (Finalize),而析构函数是作为结果执行的一段代码(成为 Finalize 的语法糖)。 它们非常接近,微软根本不应该区分它们。

Microsoft 使用 C++ 的“析构函数”术语具有误导性,因为在 C++ 中,一旦对象被删除或从堆栈中弹出,它就会在同一线程上执行,而在 C# 中,它会在另一时间在单独的线程上执行。

Wikipedia has some good discussion on the difference between a finalizer and a destructor in the finalizer article.

C# really doesn't have a "true" destructor. The syntax resembles a C++ destructor, but it really is a finalizer. You wrote it correctly in the first part of your example:

~ClassName() { }

The above is syntactic sugar for a Finalize function. It ensures that the finalizers in the base are guaranteed to run, but is otherwise identical to overriding the Finalize function. This means that when you write the destructor syntax, you're really writing the finalizer.

According to Microsoft, the finalizer refers to the function that the garbage collector calls when it collects (Finalize), while the destructor is your bit of code that executes as a result (the syntactic sugar that becomes Finalize). They are so close to being the same thing that Microsoft should have never made the distinction.

Microsoft's use of the C++'s "destructor" term is misleading, because in C++ it is executed on the same thread as soon as the object is deleted or popped off the stack, while in C# it is executed on a separate thread at another time.

葵雨 2024-08-01 20:50:38

在这里找到:http://sanjaysainitech.blogspot.com/2007/ 06/destructor-dispose.html之间的差异

  1. 析构函数

    它们是包含对象清理代码的特殊方法。
    您不能在代码中显式调用它们,因为它们被称为
    由 GC 隐式进行。 在 C# 中,它们与前面的类名具有相同的名称
    通过 ~ 符号。 喜欢-

    类 MyClass 
      { 
    
      〜我的班级() 
      { 
      …… 
      } 
      } 
      

    在 VB.NET 中,析构函数是通过重写 Finalize 来实现的
    System.Object 类的方法。

  2. 丢弃

    这些就像类中的任何其他方法一样,可以调用
    明确但它们有清理对象的特殊目的。
    在 dispose 方法中,我们为对象编写清理代码。 这是
    重要的是我们释放了处置中的所有非托管资源
    数据库连接、文件等方法。类实现
    dispose方法应该实现IDisposable接口。一个Dispose方法
    应该为它所在的对象调用 GC.SuppressFinalize 方法
    处置该类是否有析构函数,因为它已经完成了
    工作清理对象,那么就没有必要进行垃圾处理
    收集器调用对象的 Finalize 方法。 参考:
    http://msdn2.microsoft.com/en-us/库/aa720161(VS.71).aspx

  3. 最终确定

    Finalize 方法充当清理资源中的保护措施
    如果您的 Dispose 方法未被调用。 你应该只
    实现 Finalize 方法来清理非托管资源。 你
    不应该为托管对象实现 Finalize 方法,因为
    垃圾收集器自动清理托管资源。
    Finalize 方法由 GC 隐式调用,因此您不能
    从您的代码中调用它。

    注意:在C#中,Finalize方法不能被覆盖,所以你必须
    使用析构函数,其内部实现将覆盖
    MSIL中的Finalize方法。但是在VB.NET中,Finalize方法可以是
    重写,因为它支持析构函数方法。

更新: 这里有有趣的半相关线程

Found here: http://sanjaysainitech.blogspot.com/2007/06/difference-between-destructor-dispose.html

  1. Destructor

    They are special methods that contains clean up code for the object.
    You can not call them explicitly in your code as they are called
    implicitly by GC. In C# they have same name as the class name preceded
    by the ~ sign. Like-

    Class MyClass
    {
    
    ~MyClass()
    {
    .....
    }
    }
    

    In VB.NET, destructors are implemented by overriding the Finalize
    method of the System.Object class.

  2. Dispose

    These are just like any other methods in the class and can be called
    explicitly but they have a special purpose of cleaning up the object.
    In the dispose method we write clean up code for the object. It is
    important that we freed up all the unmanaged recources in the dispose
    method like database connection, files etc. The class implementing
    dispose method should implement IDisposable interface.A Dispose method
    should call the GC.SuppressFinalize method for the object it is
    disposing if the class has desturctor because it has already done the
    work to clean up the object, then it is not necessary for the garbage
    collector to call the object's Finalize method. Reference:
    http://msdn2.microsoft.com/en-us/library/aa720161(VS.71).aspx

  3. Finalize

    A Finalize method acts as a safeguard to clean up resources in the
    event that your Dispose method is not called. You should only
    implement a Finalize method to clean up unmanaged resources. You
    should not implement a Finalize method for managed objects, because
    the garbage collector cleans up managed resources automatically.
    Finalize method is called by the GC implicitly therefore you can not
    call it from your code.

    Note: In C#, Finalize method can not be override, so you have to
    use destructor whose internal implementation will override the
    Finalize method in MSIL.But in the VB.NET, Finalize method can be
    override because it does support destructor method.

Update: Interesting semi-related thread here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文