using.docx
- 文档编号:24332338
- 上传时间:2023-05-26
- 格式:DOCX
- 页数:15
- 大小:32.95KB
using.docx
《using.docx》由会员分享,可在线阅读,更多相关《using.docx(15页珍藏版)》请在冰豆网上搜索。
using
using
简介
语法
C#语言参考
1.主要用途
2.
(一).作为语句
3.示例1
4.
(二).作为指令
5.示例2
深入讨论
1.1.引言
2.2.引入命名空间
3.3.误区
4.4.强制资源清理
5.5.结论
展开
简介
语法
C#语言参考
1.主要用途
2.
(一).作为语句
3.示例1
4.
(二).作为指令
5.示例2
深入讨论
1.1.引言
2.2.引入命名空间
3.3.误区
4.4.强制资源清理
5.5.结论
展开
编辑本段简介
定义一个范围,将在此范围之外释放一个或多个对象。
编辑本段语法
using(Fontfont1=newFont("Arial",10.0f))
{
}
编辑本段C#语言参考
主要用途
using关键字有两个主要用途:
(一).作为语句
用于定义一个范围,在此范围的末尾将释放对象
C#通过.NETFramework公共语言运行库(CLR)自动释放用于存储不再需要的对象的内存。
内存的释放具有不确定性;一旦CLR决定
执行垃圾回收,就会释放内存。
但是,通常最好尽快释放诸如文件句柄和网络连接这样的有限资源。
using语句允许程序员指定使用资源的对象应当何时释放资源。
为using语句提供的对象必须实现IDisposable接口。
此接口提供了Dispose方法,该方法将释放此对象的资源。
可以在到达using语句的末尾时,或者在该语句结束之前引发了异常并且控制权离开语句块时,退出using语句。
1.可以在using语句中声明对象(如上所示),或者在using语句之前声明对象,如下所示:
Fontfont2=newFont("Arial",10.0f);
using(font2)
{
//usefont2
}
2.可以有多个对象与using语句一起使用,但是必须在using语句内部声明这些对象,如下所示:
using(Fontfont3=newFont("Arial",10.0f),font4=newFont("Arial",10.0f))
{
//Usefont3andfont4.
}
示例1
下面的示例显示用户定义类可以如何实现它自己的Dispose行为。
注意类型必须从IDisposable继承。
usingSystem;
classC:
IDisposable
{
publicvoidUseLimitedResource()
{
Console.WriteLine("Usinglimitedresource...");
}
voidIDisposable.Dispose()
{
Console.WriteLine("Disposinglimitedresource.");
}
}
classProgram
{
staticvoidMain()
{
using(Cc=newC())
{
c.UseLimitedResource();
}
Console.WriteLine("Nowoutsideusingstatement.");
Console.ReadLine();
}
}
(二).作为指令
用于为命名空间创建别名或导入其他命名空间中定义的类型
①.允许在命名空间中使用类型,这样,您就不必在该命名空间中限定某个类型的使用:
usingSystem.Text;
②.为命名空间或类型创建别名。
usingProject=PC.MyCompany.Project;
using指令的范围限制为包含它的文件。
创建using别名,以便更易于将标识符限定到命名空间或类型。
创建using指令,以便在命名空间中使用类型而不必指定命名空间。
using指令不为您提供对嵌套在指定命名空间中的任何命名空间的访问。
命名空间分为两类:
用户定义的命名空间和系统定义的命名空间。
用户定义的命名空间是在代码中定义的命名空间。
若要查看系统定义的命名空间的列表
示例2
1.下面的示例显示了如何为命名空间定义和使用using别名:
namespacePC
{
//Defineanaliasforthenestednamespace.
usingProject=PC.MyCompany.Project;
classA
{
voidM()
{
//Usethealias
Project.MyClassmc=newProject.MyClass();
}
}
namespaceMyCompany
{
namespaceProject
{
publicclassMyClass{}
}
}
}
2.下面的示例显示了如何为类定义using指令和using别名:
//cs_using_directive2.cs
//Usingdirective.
usingSystem;
//Usingaliasforaclass.
usingAliasToMyClass=NameSpace1.MyClass;
namespaceNameSpace1
{
publicclassMyClass
{
publicoverridestringToString()
{
return"YouareinNameSpace1.MyClass";
}
}
}
namespaceNameSpace2
{
classMyClass
{
}
}
namespaceNameSpace3
{
//Usingdirective:
usingNameSpace1;
//Usingdirective:
usingNameSpace2;
classMainClass
{
staticvoidMain()
{
AliasToMyClasssomevar=newAliasToMyClass();
Console.WriteLine(somevar);
}
}
}
输出:
YouareinNameSpace1.MyClass
=========================================================================================
编辑本段深入讨论
1.引言
在.NET大家庭中,有不少的关键字承担了多种角色,例如new关键字就身兼数职,除了能够创建对象,在继承体系中隐藏基类成员,还在泛型声明中约束可能用作类型参数的参数,在详细讨论using的多重身份的基础上来了解.NET在语言机制上的简便与深邃。
那么,using的多重身份都体现在哪些方面呢,我们先一睹为快吧:
·引入命名空间
·创建别名
·强制资源清理
下面,本文将从这几个角度来阐述using的多彩应用。
2.引入命名空间
using作为引入命名空间指令的用法规则为:
usingNamespace;
在.NET程序中,最常见的代码莫过于在程序文件的开头引入System命名空间,其原因在于System命名空间中封装了很多最基本最常用的操作,下面的代码对我们来说最为熟悉不过:
usingSystem;
这样,我们在程序中就可以直接使用命名空间中的类型,而不必指定详细的类型名称。
using指令可以访问嵌套命名空间。
关于:
命名空间
命名空间是.NET程序在逻辑上的组织结构,而并非实际的物理结构,是一种避免类名冲突的方法,用于将不同的数据类型组合划分的方式。
例如,在.NET中很多的基本类型都位于System命名空间,数据操作类型位于System.Data命名空间,
3.误区
·using类似于Java语言的import指令,都是引入命名空间(Java中称作包)这种逻辑结构;而不同于C语言中的#include指令,用于引入实际的类库,
·using引入命名空间,并不等于编译器编译时加载该命名空间所在的程序集,程序集的加载决定于程序中对该程序集是否存在调用操作,如果代码中不存在任何调用操作则编译器将不会加载using引入命名空间所在程序集。
因此,在源文件开头,引入多个命名空间,并非加载多个程序集,不会造成“过度引用”的弊端。
using为命名空间创建别名的用法规则为:
usingalias=namespace|type;
其中namespace表示创建命名空间的别名;而type表示创建类型别名。
例如,在.NETOffice应用中,常常会引入Microsoft.Office.Interop.Word.dll程序集,在引入命名空间时为了避免繁琐的类型输入,我们通常为其创建别名如下:
usingMSWord=Microsoft.Office.Interop.Word;
这样,就可以在程序中以MSWord来代替Microsoft.Office.Interop.Word前缀,如果要创建Application对象,则可以是这样,
privatestaticMSWord.Applicationooo=newMSWord.Application();
同样,也可以创建类型的别名,用法为:
usingMyConsole=System.Console;
classUsingEx
{
publicstaticvoidMain()
{
MyConsole.WriteLine("应用了类的别名。
");
}
}
而创建别名的另一个重要的原因在于同一cs文件中引入的不同命名空间中包括了相同名称的类型,为了避免出现名称冲突可以通过设定别名来解决,例如:
namespaceBoyspace
{
publicclassPlayer
{
publicstaticvoidPlay()
{
System.Console.WriteLine("Boysplayfootball.");
}
}
}
namespaceGirlspace
{
publicclassPlayer
{
publicstaticvoidPlay()
{
System.Console.WriteLine("Girlsplayviolin.");
}
}
}
以using创建别名,有效的解决了这种可能的命名冲突,尽管我们可以通过类型全名称来加以区分,但是这显然不是最佳的解决方案,using使得这一问题迎刃而解,不费丝毫功夫,同时在编码规范上看来也更加的符合编码要求。
4.强制资源清理
4.1由来
要理解清楚使用using语句强制清理资源,就首先从了解Dispose模式说起,而要了解Dispose模式,则应首先了解.NET的垃圾回收机制。
这些显然不是本文所能完成的宏论,我们只需要首先明确的是.NET提供了Dispose模式来实现显式释放和关闭对象的能力。
Dispose模式
Dispose模式是.NET提供的一种显式清理对象资源的约定方式,用于在.NET中释放对象封装的非托管资源。
因为非托管资源不受GC控制,对象必须调用自己的Dispose()方法来释放,这就是所谓的Dispose模式。
从概念角度来看,Dispose模式就是一种强制资源清理所要遵守的约定;从实现角度来看,Dispose模式就是让要一个类型实现IDisposable接口,从而使得该类型提供一个公有的Dispose方法。
本文不再讨论如何让一个类型实现Dispose模式来提供显示清理非托管资源的方式,而将注意集中在如何以using语句来简便的应用这种实现了Dispose模式的类型的资源清理方式。
我们在内存管理与垃圾回收章节将有详细的讨论。
using语句提供了强制清理对象资源的便捷操作方式,允许指定何时释放对象的资源,其典型应用为:
using(Fontf=newFont("Verdana",12,FontStyle.Regular))
{
//执行文本绘制操作
Graphicsg=e.Graphics;
Rectanglerect=newRectangle(10,10,200,200);
g.DrawString("Tryfinallydisposefont.",f,Brushes.Black,rect);
}//运行结束,释放f对象资源
在上述典型应用中,using语句在结束时会自动调用欲被清除对象的Dispose()方法。
因此,该Font对象必须实现IDispose接口,才能使用using语句强制对象清理资源。
我们查看其类型定义可知:
publicsealedclassFont:
MarshalByRefObject,ICloneable,ISerializable,IDisposable
Font类型的确实现了IDisposeable接口,也就具有了显示回收资源的能力。
然而,我们并未从上述代码中,看出任何使用Dispose方法的蛛丝马迹,这正式using语句带来的简便之处,其实质究竟怎样呢?
4.2实质
要想了解using语句的执行本质,了解编译器在背后做了哪些手脚,就必须回归到IL代码中来揭密才行:
.methodpublichidebysigstaticvoidMain()cilmanaged
{
.entrypoint
//代码大小40(0x28)
.maxstack4
.localsinit([0]class[System.Drawing]System.Drawing.Fontf,
[1]boolCS$4$0000)
IL_0000:
nop
IL_0001:
ldstr"Verdana"
IL_0006:
ldc.r412.
IL_000b:
ldc.i4.0
IL_000c:
newobjinstancevoid[System.Drawing]System.Drawing.Font:
:
.ctor(string,float32,
valuetype[System.Drawing]System.Drawing.FontStyle)
IL_0011:
stloc.0
.try
{
……部分省略……
}//end.try
finally
{
……部分省略……
IL_001f:
callvirtinstancevoid[mscorlib]System.IDisposable:
:
Dispose()
IL_0024:
nop
IL_0025:
endfinally
}//endhandler
IL_0026:
nop
IL_0027:
ret
}//endofmethodUsingDispose:
:
Main
显然,编译器在自动将using生成为try-finally语句,并在finally块中调用对象的Dispose方法,来清理资源。
在.NET规范中,微软建议开放人员在调用一个类型的Dispose()或者Close()方法时,将其放在异常处理的finally块中。
根据上面的分析我们可知,using语句正是隐式的调用了类型的Dispose方法,因此以下的代码和上面的示例是完全等效的:
Fontf2=newFont("Arial",10,FontStyle.Bold);
try
{
//执行文本绘制操作
Graphicsg=newGraphics();
Rectanglerect=newRectangle(10,10,200,200);
g.DrawString("Tryfinallydisposefont.",f2,Brushes.Black,rect);
}
finally
{
if(f2!
=null)
((IDisposable)f2).Dispose();
}
4.3规则
·using只能用于实现了IDisposable接口的类型,禁止为不支持IDisposable接口的类型使用using语句,否则会出现编译时错误;
·using语句适用于清理单个非托管资源的情况,而多个非托管对象的清理最好以try-finnaly来实现,因为嵌套的using语句可能存在隐藏的Bug。
内层using块引发异常时,将不能释放外层using块的对象资源。
·using语句支持初始化多个变量,但前提是这些变量的类型必须相同,例如:
using(Penp1=newPen(Brushes.Black),p2=newPen(Brushes.Blue))
{
//
}
否则,编译将不可通过。
不过,还是有变通的办法来解决这一问题,原因就是应用using语句的类型必然实现了IDisposable接口,那么就可以以下面的方式来完成初始化操作,
using(IDisposablefont=newFont("Verdana",12,FontStyle.Regular),pen=newPen(Brushes.Black))
{
floatsize=(fontasFont).Size;
Brushbrush=(penasPen).Brush;
}
另一种办法就是以使用try-finally来完成,不管初始化的对象类型是否一致。
·Dispose方法用于清理对象封装的非托管资源,而不是释放对象的内存,对象的内存依然由垃圾回收器控制。
·程序在达到using语句末尾时退出using块,而如果到达语句末尾之前引入异常则有可能提前退出。
·using中初始化的对象,可以在using语句之前声明,例如:
Fontf3=newFont("Verdana",9,FontStyle.Regular);
using(f3)
{
//执行文本绘制操作
}
5.结论
一个简单的关键字,多种不同的应用场合。
本文从比较全面的角度,诠释了using关键字在.NET中的多种用法,值得指出的是这种用法并非实现于.NET的所有高级语言,本文的情况主要局限在C#中。
扩展阅读:
∙1
∙2
开放分类:
C#
XX百科中的词条正文与判断内容均由用户提供,不代表XX百科立场。
如果您需要解决具体问题(如法律、医学等领域),建议您咨询相关领域专业人士。
172本词条对我有帮助
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- using