对象-C# 关于using代码块的疑问

问题描述

C# 关于using代码块的疑问

关于using(){ } 代码块,我之前一直以为是在()中实例化的对象,在{}结束后就被释放,也就是被置为null。今天写了如下测试代码,却发现和我之前以为的不一样,求教,所谓的释放资源具体是指什么?


using (form = new Form())
{
if (form != null)
Output("form in using");
}
Thread.Sleep(3000);
if (form != null)
{
Output("form out of using");
}
else
{
Output("form is null");
}

                    输出:form in using
                  form out of using

解决方案

 using只是语法糖,它调用了dispose方法。

using (form = new Form())
{
if (form != null)
Output("form in using");
}
相当于
try
{
    form = new Form();
    if (form != null)
        Output("form in using");
}
finally
{
    form.Dispose();
}

这两段代码完全等价。
你看,没有任何地方把form设置为null

不过一旦调用过dispose,请不要再访问这个对象(尽管可以)

解决方案二:

再多说几句。

首先,C#是自动垃圾回收的,对象没有回收一说。只要你把对象的引用设置为null了,这个对象没有任何变量引用它,垃圾回收器会在合适的时候回收它。
因此,a = null不是回收的结果,而是回收的原因。因为不再引用,所以才回收,而不是回收了,a == null了。

至于为什么要dispose方法,以及简化它的调用而出现的语法糖using,那是因为C#本身不需要你去释放什么,但是如果你调用了非托管的资源。比如说你调用了一个C++写的dll,它分配了内存,那么你需要释放它。
基于windows api的winforms库,gdi库等等都存在一些非托管的内存。而且不光是内存,像打开的文件、数据库连接、网络连接等等也需要一个关闭的过程。因此你可以编写一个dispose方法, 放上这些逻辑,并且让调用者去调用。
注意,dispose方法本身没有什么特殊的,和别的方法一样,就是一个方法而已。原则上来说,dispose本身调用过后的对象,作为调用者,你不应该再访问它了。你可以看到,form也好,control也好,都有一个bool isdisposed,用来判断这个对象是否已经调用了dispose。
dispose之后,对象作为托管的对象,还是合法存在的,除非垃圾回收。

时间: 2024-09-20 21:26:39

对象-C# 关于using代码块的疑问的相关文章

c++ 条件运算符-C++中条件运算符?:作用在代码块的疑问

问题描述 C++中条件运算符?:作用在代码块的疑问 我编写对成绩评级的代码,利用条件运算符,可是执行代码块部分却出现了问题,请指教! 编译错误提示:缺少";"(在"{"的前面) 代码如下: #include #include #include using namespace std; int main() { vector vec = { "E","D","C","B","A&

线程-关于java sychronized锁代码块对该对象的其它sychonized方法是否有影响的问题。

问题描述 关于java sychronized锁代码块对该对象的其它sychonized方法是否有影响的问题. 代码是书上例子,我简化了,启用线程ob1后,通过主线程调用sychonized方法mysuspend()和myresume()来控制ob1线程的等待与重启.线程从15开始倒数,0.5秒个,主线程在1秒时候暂停文字提示,再过1秒重启线程.例子中的sychonized代码块仅包含wait()判定部分,输出与预期一样,倒数到14的时候中断,之后又恢复.但是当我将sychonized代码块前移

Java面向对象基础--代码块

1.普通代码块 public class CodeDemo01{ public static void main(String args[]){ { // 普通代码块 int x = 30 ; // 就属于一个局部变量 System.out.println("普通代码块 --> x = " + x) ; } //int x = 100 ; // 与局部变量名称相同 System.out.println("代码块之外 --> x = " + x) ; }

JAVA之旅(四)——面向对象思想,成员/局部变量,匿名对象,封装 , private,构造方法,构造代码块

JAVA之旅(四)--面向对象思想,成员/局部变量,匿名对象,封装 , private,构造方法,构造代码块 加油吧,节奏得快点了 1.概述 上篇幅也是讲了这点,这篇幅就着重的讲一下思想和案例 就拿买电脑来说吧,首先,你不懂电脑,你去电脑城买电脑,和大象装冰箱里一样,是什么步骤?咨询 砍价 ,谈妥了就那电脑走人,对吧,这就是面向过程的思想,而面向对象是:你有一个哥们,他懂电脑,什么都会,你只要带他去,就行,你这个哥们就是对象,在JAVA中,我们就是操作一个对象去完成各种各样的操作的,这就是面向对

Ruby的代码块、迭代子和过程对象

在Ruby的一切都是一个对象.甚至一个代码块也是一个对象!在Ruby中,代码对象被称为代码块.你可以把代码块想像成小的程序单元.它们包含Ruby代码并且能够在执行它们时转入到方法中.在Python,C和Java中与之类似的概念是函数指针,匿名函数,内部类和回调函数. Ruby代码块的语法是,把Ruby代码放在大括号之间或放在do/end命令之间.如下所示: { #这是一个代码块... } do #...并且这也是一个代码块 end 在一个很简单的实例中,{puts"hello world&quo

Java 25天基础-DAY 06-面向对象-静态代码块

/* 静态代码快 格式: static { 静态代码块中的执行语句. } 特点:随着类的加载而执行,只执行一次.优先于主函数执行. 用于给类进行初始化 / / class StaticCode { static { System.out.println("a"); } } */ class StaticCodeDemo { static { System.out.println("b"); } public static void main(String[] arg

JAVA里synchronized同步代码块的一点疑问

问题描述 代码如下:public class SomeObj { public void print(int i){ System.out.println(Thread.currentThread().getName()+DateHelper.getNow()+ " " + i); try { wait(1000); } catch (InterruptedException e) { e.printStackTrace(); } }}public class ThreadA exte

Objective-C语法之代码块(block)的使用

代码块本质上是和其他变量类似.不同的是,代码块存储的数据是一个函数体.使用代码块是,你可以像调用其他标准函数一样,传入参数数,并得到返回值. 脱字符(^)是块的语法标记.按照我们熟悉的参数语法规约所定义的返回值以及块的主体(也就是可以执行的代码).下图是如何把块变量赋值给一个变量的语法讲解: 按照调用函数的方式调用块对象变量就可以了: int result = myBlock(4); // result是 28 1.参数是NSString*的代码块 [cpp] view plaincopy vo

java中static{.......}代码块的作用

问题描述 java中static{.......}代码块的作用 java中static{.......}代码块主要用在哪里,表示什么意思,有什么用,里面主要写什么内容 解决方案 static后不跟方法名,这个块在该类第一次加载的时候运行,就是说比初始化模块还早就运行,一般用于加载该类需要一次性完成的功能使用. 解决方案二: Java中的static静态代码块 解决方案三: 初始化用,不需要创建实例,当你访问这个类时,就会执行 解决方案四: static 就是静态.你可以搜索一下关于静态的解释.网