推广 热搜: csgo  vue  angelababy  2023  gps  新车  htc  落地  app  p2p 

C#中的对象资源释放

   2023-07-27 网络整理佚名1850
核心提示:释放资源主要有两种方式,其一是对象实现接口,由程序员调用.()方法来释放资源;其二是通过重写继承自对象的虚方法()来释放资源。重要点:只有通过程序显式或非显式调用方法,才会通过该方法释放资源。//close()释放资源,实质上就是隐式调用了()释放了资源。()来代替()方法,在析构函数中写释放资源的代码。//这个地方方式编译后的释放资源的代码方法,那么在垃圾回收的时候就会调用释放资源的代码。

C#本身不需要程序员对所有托管对象进行干预(注:不需要干预,当然资源消耗很大,如果需要的话可以做一些干预来提高程序性能,比如通过代码控制垃圾回收)部分),但对于非托管资源(文件、流、数据库连接、GDI+对象、COM对象等),则需要程序来控制资源的释放。

释放资源的方式主要有两种,一种是对象实现接口,程序员调用.()方法释放资源;另一种是对象实现接口,程序员调用.()方法释放资源; 另一种是通过重写从对象继承的虚方法()来释放资源。

(1)----------(注:实现变成“一次性类型”)

{空白 ();}

说明:垃圾收集器GC不支持该接口,无法通过自动垃圾收集机制调用该方法或手动调用GC.()方法。

重要提示:仅当程序显式或隐式调用该方法时,该方法才会释放资源。 所谓显示调用,就是直接在代码中写()来带调用。 关于隐式调用,常见的有两种:

(1)一是使用using关键字

使用( sw=new (,true))

// 处理完代码后,将调用该方法。 即使发生异常,该方法也会被调用。本质上,中间代码转换为try{}{},在{}中调用该方法,所以不用担心因为异常而调用不到该方法

(2)关于方法的隐式调用,另一种常见的就是方法的间接调用。 常见的就是一些类库中的别名调用,例如

fs=new("abc.txt", .);

//

fs.close(); //close()释放资源,本质上是隐式调用()来释放资源。 注意:如果调用()而不是close(),效果是一样的。

(2)()方法和析构函数~()-----(注:重载称为“终端类型”)

要点:是基类定义的虚方法; GC在垃圾回收时会调用()方法; 在自己的程序中,不能通过c#直接重载()方法,会出现编译错误,什么? 为什么? 如何? 那我们该怎么办呢? 答案是:使用析构函数~()而不是()方法,并在析构函数中编写释放资源的代码。

班级

void (){} // 无法编译,编译失败

//为什么会这样。 该方法原本是类定义的受保护的虚方法(),但是这里不能重写? ? ?

//不知道微软是怎么处理的,但是我们继承不了,而且我们也没什么可做的,所以就别这么做了。 微软希望我们直接写析构函数~(){}

班级

void (){} // 无法编译,编译失败

〜()

; //这里写释放资源的代码

仔细验证后发现,析构函数编译后,会在中间代码中转化为()方法,所以c#析构函数本质上就是()方法。 然而,编译器在从析构函数到()方法的转换过程中会添加一些额外的代码。 通过.exe查看c#析构函数的编译代码,可以发现编译器添加了一些错误检测代码。 分析中间代码可以看出,程序员写的代码都会放在中间代码的try{}块中,并且有些代码放在中间代码块中是为了保证基类的方法始终被执行。 下面是编译后的中间代码的部分展示,以说明编译后的析构函数是什么样子的。

.void () cil //显然编译出来的析构函数就是()方法

。 1

。尝试

....

//这里是编译后释放资源的代码

...

……

:

call void [] .::() //调用父类的方法

……

因此,析构函数(或方法)首先调用本类中需要析构的资源,然后再调用父类的()继续析构,这样可以保证基类的资源被正确释放。

例如,以下代码:

班级

〜()

.(" ");

班级:

〜()

.(" ");

班级

无效主([]参数)

p = new();

p = 空;

GC。();

GC.zers();

。读();

上述代码执行后,会输出:

即先执行子类的析构函数,然后执行父类的析构函数。

(3)同时实现并重载()方法的类(--------注:成为一次性且可终结的类型)

如果你只实现方法而没有重载()(注意:重载是析构函数的定义,因为析构函数是编译后的重载()方法),那么如果你忘记调用该方法,那么非托管资源可能会停留在永远在记忆中。

您可以同时实现方法和重载()方法。 如果在方法中调用GC.()通知垃圾收集器跳过终结过程,那么在()之后,当GC回收时,()方法中的代码将不会被调用。 但如果用户忘记调用该方法,则垃圾回收期间将调用释放资源的代码。

微软提供的样板代码如下:

班级:

布尔=假;

空白 ()

(真的);

GC.(这个);

无效(布尔)

如果这。)

如果()

//这里释放托管资源

//这里释放非托管资源

=真;

〜()

(错误的);

 
反对 0举报 0 收藏 0 打赏 0评论 0
 
更多>同类资讯
推荐图文
推荐资讯
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报
Powered By DESTOON