C#终结器妙用

熟悉C#的程序员都知道,在C#类中,有一种函数类似于C++类析构函数,它们的表达方式也一样,都是 ~。没错,它就是C#中的终结器。

乍看之下,C#终结器和C++析构函数好像一样,相同的表达方式,同样一个类只能有一个,同样是在类对象被销毁的时候由系统调用。

但是由于C#垃圾回收机制的存在,C#终结器并不能所分配的类对象超出其生命周期的时候及时被调用,它只会被垃圾回收器标记,并在垃圾回收器运行的时候调用。换言之,终结器被调用的时机不定,我们只知道终结器要被调用,但是什么时候被调用就只有垃圾回收器才知道了。

正因为如此,终结器在C#中出场的次数寥寥可数,远不及析构函数在C++那边的出场率。毕竟,一个不知道什么时候会被调用的函数,在大部分情况下是没什么用处的。

不过,在某些场景下面,终结器仍然是有用的。

举个栗子

想象我们有个类,类中有个Close方法,为了确保类对象的状态正确,我们在每次使用完类对象的时候,需要调用Close方法。我们会怎么做呢?

添加using

实现Disposable接口,确保Dispose方法调用Close方法并在使用类的时候加上using语句。

	public class MustCloseProperly : IDisposable
    {
        public MustCloseProperly()
        {
            //something important created
        }

        public void Dispose()
        {
        	Close();
        }
        
        public void Close()
        {
        	//close it
		}
		
        public void DoSomething()
        {
            //do something
        }
    }
	
	public static void Main()
	{
		using(MustCloseProperly obj = new MustCloseProperly())
		{
			obj.DoSomething();
		}
	}

这种办法可行,也是大家常见的一种方法。但是这儿也会有一个问题,如果有些程序员大意了,没有使用using, 也没有显式调用Close,那我们有没有办法知晓呢?

第二层检查

这个时候,我们就需要利用终结器了。添加终结器,在Close中添加语句取消终结器。这样,如果终结器被触发,那么我们就可以肯定至少有类对象没有被正确的关闭。

public class MustCloseProperly
{
	public void Close()
	{
		//close it
		GC.SuppressFinalize(this);
	}
    ~MustCloseProperly()
    {
        Debug.Assert(false, "you must dispose this object explicitly");
    }
}

这样,当有程序员忘记了使用using并且也没有显式调用Close的时候,程序或迟或早,会以断言的形式提醒用户。当然,这取决于终结器何时调用,至于终结器何时调用,这又是另外一个话题,涉及到内存的使用率和垃圾回收器的运行机制,有机会我们再说。

但是这个方法不是万无一失的,如果一个程序运行的特别快,使用的内存也特别少,那么很有可能垃圾回收器还没有来得及运行程序就顺利结束了,错误也就被掩盖了。所以这个方法不是100%保险。如果小伙伴有更好更保险的检测方法,请留言告诉我哟!当然最好的办法是坚持对Dispose对象使用using。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值