1、using(){}的用法
using语句 using 语句允许程序员指定使用资源的对象应当何时释放资源。using 语句中使用的对象必须实现 IDisposable 接口。此接口提供了 Dispose 方法,该方法将释放此对象的资源。 ①可以在 using 语句之中声明对象。 Font font2 = new Font("Arial", 10.0f); using (font2) { // use font2 } ②可以在 using 语句之前声明对象。 using (Font font2 = new Font("Arial", 10.0f)) { // use font2 } ③可以有多个对象与 using 语句一起使用,但是必须在 using 语句内部声明这些对象。 using (Font font3=new Font("Arial",10.0f), font4=new Font("Arial",10.0f)) { // Use font3 and font4. } 使用规则 ①using只能用于实现了IDisposable接口的类型,禁止为不支持IDisposable接口的类型使用using语句,否则会出现编译错误; ②using语句适用于清理单个非托管资源的情况,而多个非托管对象的清理最好以try-finnaly来实现,因为嵌套的using语句可能存在隐藏的Bug。内层using块引发异常时,将不能释放外层using块的对象资源; ③using语句支持初始化多个变量,但前提是这些变量的类型必须相同,例如: using(Pen p1 = new Pen(Brushes.Black), p2 = new Pen(Brushes.Blue)) { // } ④针对初始化对个不同类型的变量时,可以都声明为IDisposable类型,例如: using (IDisposable font = new Font("Verdana", 12), pen = new Pen(Brushes.Black)) { float size = (font as Font).Size; Brush brush = (pen as Pen).Brush; } using实质 在程序编译阶段,编译器会自动将using语句生成为try-finally语句,并在finally块中调用对象的Dispose方法,来清理资源。所以,using语句等效于try-finally语句,例如: Font f2 = new Font("Arial", 10, FontStyle.Bold); try { //执行文本绘制操作 } finally { if (f2 != null) ((IDisposable)f2).Dispose(); }
2、string.Empty
string s;
string s=null;
string s="";
string s=String.Empty; 的区别
null名词解释:(MSDN)null是一个字面文本,它代表空引用,即引用变量没有引用( 指向)到任何对象,它是引用类型的默认值。 同样会在栈上保存一个地址,这个地址也占4字节,但是这个地址是没有明确指向的,它哪也不指,其内容为0x00000000。
string s;
该语句表示只是声明了一个引用变量,但是并没有初始化引用,所以对变量s的任何操作(除了初始化赋值外)都将引发异常。
string s=null;
该语句表示声明了一个引用变量并初始化引用,但是该引用没有指向任何对象,但可以把它作为参数传递或其它使用,但是不能调用它作为对象的方法 ,如toString,getHashCode等。
string s="";
该语句表示声明 并引用到一个对象,只不过这个对象为0个字节 .所以既然有了对象,就可以调用对象的方法,
string s=String.Empty;
String中Empty的源码定义:
publci static readonly string Empty = "";
如果你不知道static readonly的作用,自己搜下,我简单说下为什么String.Empty可能会比用String s = ""高效:
需要知道的知识: 在C#中,所有的字符串都是以HashTable来存放的,key是字符串,value字符串的地址,当用string str = ""的时候,首先会去HastTable中查找""然后,再将""的地址赋给str,这经历了两个过程。而string.Empty,相当于,首先我定义 了一个引用,那么这个引用的地址是指向""的实际地址,所以,我用string str = string.Empty的时候,相当于我只是把""的实际地址赋给str,这样省去了在Hashtable中的定位过程,所以在一定程度上提高的效率。
对于网络很多人都认为定义string s=String.Empty没有分配空间,而string s="";分配了空间,实际上都没有分配空间,这其中还涉及一个字符串的内存的驻留机制,我觉得在C#中的内存驻留机制中,已经存在一个""空字符串,所以无论你是string s=String.Empty和string s=""都是不会创建一个新的空间,只是引用,引用""空字符串的内存位置。
http://www.bitscn.com/pdb/dotnet/201003/181883.html
3、partial修饰符
Partial是局部类型的意思。允许我们将一个类、结构或接口分成几个部分,分别实现在几个不同的.cs文件中。C#编译器在编译的时候仍会将各个部分的局部类型合并成一个完整的类
局部类型适用于以下情况:
(1) 类型特别大,不宜放在一个文件中实现。
(2) 一个类型中的一部分代码为自动化工具生成的代码,不宜与我们自己编写的代码混合在一起。
(3) 需要多人合作编写一个类。
局部类型的限制
(1) 局部类型只适用于类、接口、结构,不支持委托和枚举。
(2) 同一个类型的各个部分必须都有修饰符 partial。
(3) 使用局部类型时,一个类型的各个部分必须位于相同的命名空间中。
(4) 一个类型的各个部分必须被同时编译。
3. 局部类型的注意点
(1) 关键字partial是一个上下文关键字,只有和 class、struct、interface 放在一起时才有关键字的含义。因此partial的引入不会影响现有代码中名称为partial的变量。
(2) 局部类型的各个部分一般是分开放在几个不同的.cs文件中,但C#编译器允许我们将他们放在同一文件中。
4. 局部类型的应用特性
在局部类型上的特性具有“累加”效应。
[Attribute1, Attribute2("Hello")]
partial class Class1{}
[Attribute3, Attribute2("Exit")]
partial class Class1{}
相当于
[Attribute1, Attribute2("Hello"), Attribute3, Attribute2("Exit")]
class Class1 {}
注:Attribute2属性允许在类上多次使用。
5. 局部类型上的修饰符
(1) 一个类型的各个部分上的访问修饰符必须维持一致性。
(2) 如果一个类型有一个部分使用了abstract修饰符,那么整个类都将被视为抽象类。
(3) 如果一个类型有一个部分使用了 sealed 修饰符,那么整个类都将被视为密封类。
(4) 一个类的各个部分不能使用相互矛盾的修饰符,比如不能在一个部分上使用abstract,又在另一个部分上使用sealed。
6. 局部类型的基类和接口
(1) 一个类型的各个部分上指定的基类必须一致。某个部分可以不指定基类,但如果指定,则必须相同。
(2) 局部类型上的接口具有“累加”效应。
partial class Class2: Iinterface1, Iinterface2 {}
partial class Class2: Iinterface3 {}
partial class Class2: Iinterface2 {}
相当于
class Class2: Iinterface1, Iinterface2, Iinterface3 {}