【问题标题】:Why can't static classes have destructors?为什么静态类不能有析构函数?
【发布时间】:2010-12-20 19:02:54
【问题描述】:

两部分:

  1. 如果静态类可以有静态构造函数,为什么不能有静态析构函数?

  2. 最好的解决方法是什么?我有一个静态类来管理作为 COM 对象的连接池,如果程序中的其他地方发生故障,我需要确保它们的连接被关闭/释放。

【问题讨论】:

    标签: c# .net static destructor


    【解决方案1】:

    您应该使用具有单例模式的普通类而不是静态类(也就是说,您保留一个类的单个实例,可能由类本身的一个静态属性引用)。然后你可以有一个析构函数,甚至更好,析构函数和Dispose方法的组合。

    例如,如果您现在有:

    static class MyClass
    {
        public static void MyMethod() {...}
    }
    
    //Using the class:
    MyClass.MyMethod();
    

    你会:

    class MyClass : IDisposable
    {
        public static MyClass()
        {
            Instance=new MyClass();
        }
    
        public static MyClass Instance {get; private set;}
    
        public void MyMethod() {...}
    
        public void Dispose()
        {
            //...
        }
    
        ~MyClass()
        {
            //Your destructor goes here
        }
    }
    
    //Using the class:
    MyClass.Instance.MyMethod();
    

    (注意实例是如何在静态构造函数中创建的,它在第一次引用任何类静态成员时被调用)

    【讨论】:

    • 谢谢。我还在我的代码中添加了一个私有非静态构造函数,因此该类不能在其他地方实例化。
    • 这里有一个很好的指南,介绍了使用线程安全执行单例模式的所有不同方法。 csharpindepth.com/Articles/General/Singleton.aspx
    • 析构函数通常会调用Dispose吗?
    • 在 Delphi 中,静态类有 ctor 和 dtor :-)
    【解决方案2】:
    1. 静态类没有析构函数,因为静态类永远不会被销毁。

    2. 如果你想创建和销毁它的多个实例,它不应该是静态的。让它成为一个完整的课程。

    3. 无论如何都不应该将析构函数用于此目的。使用 IDisposable / Dispose。

    【讨论】:

    • 为什么编译器允许你拥有一个? static ~ClassName(){ } 它永远不会运行吗?
    【解决方案3】:

    1.为什么? -- 一个类型本身不能有一个构造函数,就像你通常认为的实例上的构造函数一样。一般来说,它有时被称为“静态初始化”方法,但微软使用术语“类型构造函数”(并且它有特殊限制)——你在其中放入代码来初始化类型/类——如果它是一个实例构造函数,它可能是超载。这种对“类型构造函数”的静态限制是因为 .NET CLR 负责在堆上加载类模板,并且不允许在这种情况下指定参数(因为您将如何传递参数)。因为从最严格的意义上说,程序员不负责导致调用类型构造函数,所以当静态析构函数更多地位于 CLR 的域中时,允许程序员编写静态析构函数没有多大意义。 CLR 最终会从堆中删除类模板,但类模板的生命周期比它的实例长,所以无论如何你都不想在其中做任何资源密集型的事情(例如保持打开一个数据库连接)。

    2。什么? - 单身人士 如果您遇到需要在类模板上打开资源并随后将其销毁的情况,您可能会认为Singleton software pattern 仅具有该类的一个实例,并且可能还实现System.IDiposable 接口以除了析构函数之外,还有助于清理。 (我看到有人已经在 IDisposable 代码示例中击败了我,所以我将在这里结束我的解决方案。)

    【讨论】:

      【解决方案4】:

      静态类永远不会被破坏。它与程序一起终止。您可以使用单例模式作为实现,而不是使用静态类

      【讨论】:

      • 你确定一个 Class(-type) 没有被垃圾回收吗?
      • @HenkHolterman 是的。没有什么可以收集的。由于所有属性/字段都至少有一个引用(静态类),并且由于静态类的范围是从第一次访问到程序终止,所以没有什么可以收集
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-05
      • 2012-08-30
      • 2023-03-06
      • 1970-01-01
      • 2011-05-29
      • 2021-10-07
      • 2011-12-08
      相关资源
      最近更新 更多