C#中的构造函数和终结器

目录

1、构造函数的概念及使用 

2、终结器的概念及使用      

3、总结


        构造函数和析构函数是类中比较特殊的两种成员函数,主要用来对对象进行初始化和回收对象资源。

        一般来说,对象的生命周期从构造函数开始,以析构函数结束。如果一个类含有构造函数,在实例化该类的对象时就会调用,如果含有析构函数,则会在销毁对象时调用。构造函数的名字和类名相同,析构函数和构造函数的名字相同,但析构函数要在名字前加一个波浪号~。以往,当退出含有该对象的成员时,析构函数将自动释放这个对象所占用的内存空间。  

1、构造函数的概念及使用 

        构造函数是在创建给定类型的对象时执行的类方法。构造函数具有与类相同的名称,它通常初始化新对象的数据成员。

        不带参数的构造函数称为“默认构造函数”。无论何时,只要使用new运算符实例化对象,并且不为 new提供任何参数,就会调用默认构造函数。

//构造函数
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Test9_2
{
    class Program
    {
        public int x = 3;                           //定义int型变量,作为加数
        public int y = 5;							//定义int型变量,作为被加数
        public int z = 0;                           //定义int型变量,记录加法运算的和
        public Program()
        {
            z = x + y;                              //在构造函数中为和赋值
        }
        static void Main(string[] args)
        {
            if (args is null)                        //解除IDE0060
            {
                throw new ArgumentNullException(nameof(args));
            }
            Program program = new();                //使用构造函数实例化Program对象
            Console.WriteLine("结果:" + program.z);//使用实例化的Program对象输出加法运算的和
            Console.Read();
        }

    }
}
/*运行结果:
结果:8    */

2、终结器的概念及使用      

        终结器(以前称为析构器)用于在垃圾回收器收集类实例时执行任何必要的最终清理操作。

        终结器隐式调用对象基类上的 Finalize。 因此,对终结器的调用会隐式转换为以下代码:

protected override void Finalize()
{
    try
    {
        // Cleanup statements...
    }
    finally
    {
        base.Finalize();
    }
}

        这种设计意味着,对继承链(从派生程度最高到派生程度最低)中的所有实例以递归方式调用 Finalize 方法。

        不应使用空终结器。不必要的终结器会导致不必要的性能损失。

        应尽可能避免终结器,因为跟踪对象生存期会产生额外的性能系统开销。 垃圾回收器在收集对象之前运行终结器。

        如果调试需要终结器,请将整个终结器置于 #if DEBUG / #endif 指令中。

public class Class3 
{ 
#if DEBUG 
// Violation will not occur because the finalizer will exist and 
// contain code when the DEBUG directive is present. When the 
// DEBUG directive is not present, the finalizer will not exist, 
// and therefore not be empty. 
~Class3() 
{ Debug.Fail("Finalizer called!"); } 
#endif 
}

        对于终结器是否在应用程序终止过程中运行,这特定于每个 .NET 的实现 .NET 5(包括 .NET Core)及更高版本不会在应用程序终止过程中调用终结器。

//析构函数
//CA1821:移除空终结器或需要#if DEBUG/#endif
//.NET Framework:输出显示当应用程序终止时,这三个类的终结器将按照派生程度最高到最低的顺序自动进行调用。
//.NET 5(包括 .NET Core)或更高版本:没有输出,因为在应用程序终止时,此 .NET 的实现不调用终结器。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Test9_3
{
    class Program
    {
        public Program()
        {
            Console.WriteLine("我是构造函数");
        }
#if DEBUG                                          //.NET5以上即使采用#if DEBUG /#endif也是徒劳的
        ~Program()								   //析构函数
        {
            Console.WriteLine("析构函数自动调用");  //输出一个字符串
        }
#endif
        static void Main(string[] args)
        {
            if (args is null)                       //解除IDE0060
            {
                throw new ArgumentNullException(nameof(args));
            }
            Program program = new();                //实例化Program对象      
        }

    }
}
/*运行结果:
我是构造函数  */

3、总结

         这篇关于构造函数和终结器的总结,最有价值的地方是关于终结器的新说法。以往在.NET5以下如果在类中定义了终结器,在应用程序终止过程中调用终结器。但在.NET5以上即使在类中定义了终结器,即使将整个终结器置于 #if DEBUG / #endif 指令中,都不会在应用程序终止过程中调用终结器。

猜你喜欢

转载自blog.csdn.net/wenchm/article/details/131586913