永发信息网

关于C#的close()方法

答案:3  悬赏:30  手机版
解决时间 2021-11-13 15:03
关于C#的close()方法
最佳答案
问题实际上是出在你的这段代码上
Form1 f1 = new Form1();
new Form1()的意思是在你的内存中新建一个类型为 Form1的对象
而实际上你的内存中已经存在了一个类型为Form1的对象即当前窗体this, 当你调用f1.Close()的时候,只不过是关闭了刚才新建的类型为Form1的对象f1而已,而不是关闭当前窗体。
因此,关闭当前窗体的办法只能是
this.Close()(this可以省略);

实际上在C#中很多方法和属性的使用上都是这个道理,而不仅仅是关闭窗体的Close()方法
全部回答
对于f1这个新生成的对象,你还没有f1.Show()呢,怎么能f1.Close()啊。
要关闭的话,可以这样做:

Form1 f1 = new Form1(); //在事件方法体外面实例化一个窗体对象

private void button1_Click(object sender, EventArgs e) //打开窗体
{
f1.Show();
}

private void button2_Click(object sender, EventArgs e) //关闭窗体
{
f1.Close();
}
一:什么是资源
在开始本文前,需要一些准备知识。首先要提出“什么是资源”。在CLR出来之后,Windows系统资源开始分为“非托管资源”和“托管资源”。
非托管资源是指:所有的Window内核对象(句柄)都是非托管资源,如对于Stream,数据库连接,GDI+的相关对象,还有Com对象等等,这些资源并不是受到CLR管理;
托管资源是指:由CLR管理分配和释放的资源,即由CLR里new出来的对象。
其次再来讲,资源的释放方式。
非托管资源:需要显式释放的,也即需要你写代码释放;
托管资源:并不需要显式释放,但是如果引用类型本身含有非托管资源,则需要进行现实释放;
二:显式释放的C#实现
显式释放的C#实现,由C#语法支持的有:
1:实现IDisposable接口的Dispose方法;
2:析构方法(终结器);
不由C#语法支持,但是约定支持的显式释放是:
3:提供显示释放方法,比如常用的Close方法;
三:Dispose、Close和析构方法异同点
但是,还需要区分这3种方式的异同点。首先,你无法调用析构方法。析构方法是由垃圾回收机制进行调用的。换句话来说,就是你不知道析构方法被调用的时机。严格意义上来说,它只是作为资源释放的一个补救措施。
资源释放的一个正确的措施是为类型实现IDisposable接口的Dispose。当你需要释放类型的资源的时候,应该显示的调用Dipose方法。当然,这里还有一个C#的语法糖,就是使用using程序块,在离开using程序块的时候,CLR会自动调用类型所创建对象的Dipose方法。
可能有人会问道,既然可以通过Dispose方法的方式来进行资源的释放,为什么有些类型还需要提供一个Close方法。这里面的区别,或者说约定在于,如果你仔细观察这些类型:他们基本都只公开了Close方法,他们都实现了IDisposable,但都隐藏了Dispose方法。以Socket这个类为例,它:
1:提供public void Close()
public void Close()
{
//….
((IDisposable)this).Dispose();
//….
}
2:提供显式void IDisposable.Dispose()
void IDisposable.Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
3:提供protected virtual void Dispose(bool disposing)。真正的资源释放的代码放在这里。
所以理论上来将,提供Close方法最终还是使用的Dispose方法,之所以这么做,是因为这些类型出于显式实现IDisposable的因素,在调用这些Dispose方法的时候,必须完成一次转型,如:
((IDisposable)new A()).Dispose();
为了避免转型,同时也为了避免不熟悉C#语法的开发人员更直观的释放资源,提供了Close方法。
在上文的例子中,你可能已经注意到IDisposable.Dispose这个方法中,包含一句:
GC.SuppressFinalize(this);
这是告诉CLR,在进行垃圾回收的时候,不用再继续调用析构方法(终结器)了。是的,因为你已经手动释放资源了。这也从另一个方面验证了析构方法只是作为资源释放的补救机制。因为假设你忘记Close或者Dispose了,CLR会在垃圾回收的时候为你做这件事。查看Socket的析构函数,你会很好的理解这一点。
~Socket()
{
this.Dispose(false);
}
是的,析构方法调用的也是Dispose。
备注1:本文带来几个争论
1:托管资源本身是否需要显式释放。答案显然是:不需要;
2:如果引用类型对象不再需要,是否需要显式=null;答案是:即使不这样做,GC也会进行垃圾回收。
3:将托管资源分为引用类型资源和值类型资源这种分类方法是有问题的,或者说是错误的。正确的分类法应该是栈资源和堆资源。线程栈中存放的是方法的实参和方法内部的局部变量。堆上存放的是类型对象本身及对象的两个额外成员:类型对象指针和同步块索引。
4:Dispose方法本身是用来让你放置资源清理代码的。显然,一个空方法并不代表清理工作本身,真正执行清理工作的是你具体的代码。
备注2:推荐Dipose模式实现
如:基类
代码
class ClassShouldDisposeBase : IDisposable
{
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (disposing)
{
//执行基本的清理代码
}
}

~ClassShouldDisposeBase()
{
this.Dispose(false);
}

}
子类:
代码
class ClassShouldDispose: ClassShouldDisposeBase
{
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// 执行子类清理代码
// 如有必要,执行base.Dispose(disposing);
}
else
{
// 如有必要,执行base.Dispose(disposing);
}
}

public void Close()
{
//调用本类或者基类的Dispose方法
//其它代码
}
}
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
概率论:随机变量X~N(220,3²),Y~N(225,4
万泉商城停车场(出入口)地址在哪,我要去那里
假如有一个环网柜,两进一出??
请教一道生物题(灌水抄袭勿入谢谢)
物理中大r和小r一般都代表什么意思啊
木门套线需要切45度那么它总长怎么算才准确
仲恺围棋培训地址在什么地方,想过去办事,
为什么说四川一带是中国的国防重地
一台四冲程内燃机转速为600r/min,则
哪里我有可将12伏直流电升压成万伏交流电的升
五元炼钢工人的纸币值多少钱?
我前几天买了个空调,等了2天安装后,发现是
东营供电所待遇
天刀家具风水值怎么刷
小鸟3号英文版
推荐资讯
做售后维修学什么专业
谁知道贴宣传单用的胶水怎么做才好用?
为什么君士坦丁十一世宁可战死
威尔逊刀模机械制造公司这个地址在什么地方,
WLK国服奥法要多少命中?
成年的竹子大约多高
王俊凯对王源易洋千玺做的n件 暖心小事
九月份的羊好吗
粉彩和水粉是一种颜料吗?有什么区别?
孩子老是反复的问同一问题,怎么办
有一台玉才4110的发动机大修之后老冲缸垫请问
骶1隐性脊柱裂
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?